mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-02 04:48:27 +00:00
Port the Skia renderer to rwh06 and the new softbuffer
... by accepting an Rc<dyn Has*Handle> in the interface. This is required for softbuffer use.
This commit is contained in:
parent
40f2833bac
commit
4c888bf1ae
10 changed files with 156 additions and 123 deletions
|
|
@ -511,18 +511,34 @@ mod software_renderer {
|
|||
pub mod skia {
|
||||
use super::*;
|
||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
||||
use std::rc::Rc;
|
||||
|
||||
struct CppRawHandle(RawWindowHandle, RawDisplayHandle);
|
||||
struct RawHandlePair((RawWindowHandle, RawDisplayHandle));
|
||||
|
||||
// the raw handle type are #[non_exhaustive], so they can't be initialize with the convenient syntax. Work that around.
|
||||
macro_rules! init_raw {
|
||||
($ty:ty { $($var:ident),* }) => {
|
||||
{
|
||||
let mut h = <$ty>::empty();
|
||||
$(h.$var = $var;)*
|
||||
h
|
||||
}
|
||||
};
|
||||
impl raw_window_handle::HasDisplayHandle for RawHandlePair {
|
||||
fn display_handle(
|
||||
&self,
|
||||
) -> Result<raw_window_handle::DisplayHandle<'_>, raw_window_handle::HandleError> {
|
||||
// Safety: It is assumed that the C++ side keeps the window/display handles alive.
|
||||
Ok(unsafe { raw_window_handle::DisplayHandle::borrow_raw(self.0 .1) })
|
||||
}
|
||||
}
|
||||
|
||||
impl raw_window_handle::HasWindowHandle for RawHandlePair {
|
||||
fn window_handle(
|
||||
&self,
|
||||
) -> Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError> {
|
||||
// Safety: It is assumed that the C++ side keeps the window/display handles alive.
|
||||
Ok(unsafe { raw_window_handle::WindowHandle::borrow_raw(self.0 .0) })
|
||||
}
|
||||
}
|
||||
|
||||
struct CppRawHandle(Rc<RawHandlePair>);
|
||||
|
||||
impl From<(RawWindowHandle, RawDisplayHandle)> for CppRawHandle {
|
||||
fn from(pair: (RawWindowHandle, RawDisplayHandle)) -> Self {
|
||||
Self(Rc::new(RawHandlePair(pair)))
|
||||
}
|
||||
}
|
||||
|
||||
type CppRawHandleOpaque = *const c_void;
|
||||
|
|
@ -530,15 +546,14 @@ pub mod skia {
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_new_raw_window_handle_win32(
|
||||
hwnd: *mut c_void,
|
||||
hinstance: *mut c_void,
|
||||
_hinstance: *mut c_void,
|
||||
) -> CppRawHandleOpaque {
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::Win32(init_raw!(raw_window_handle::Win32WindowHandle {
|
||||
hwnd,
|
||||
hinstance
|
||||
})),
|
||||
RawDisplayHandle::Windows(raw_window_handle::WindowsDisplayHandle::empty()),
|
||||
);
|
||||
let handle = CppRawHandle::from((
|
||||
RawWindowHandle::Win32(raw_window_handle::Win32WindowHandle::new(
|
||||
(hwnd as isize).try_into().expect("C++: NativeWindowHandle created with null hwnd"),
|
||||
)),
|
||||
RawDisplayHandle::Windows(raw_window_handle::WindowsDisplayHandle::new()),
|
||||
));
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
|
|
@ -550,10 +565,21 @@ pub mod skia {
|
|||
screen: core::ffi::c_int,
|
||||
) -> CppRawHandleOpaque {
|
||||
use raw_window_handle::{XcbDisplayHandle, XcbWindowHandle};
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::Xcb(init_raw!(XcbWindowHandle { window, visual_id })),
|
||||
RawDisplayHandle::Xcb(init_raw!(XcbDisplayHandle { connection, screen })),
|
||||
);
|
||||
let handle = CppRawHandle::from((
|
||||
RawWindowHandle::Xcb({
|
||||
let mut hnd = XcbWindowHandle::new(
|
||||
window
|
||||
.try_into()
|
||||
.expect("C++: NativeWindowHandle created with null xcb window handle"),
|
||||
);
|
||||
hnd.visual_id = visual_id.try_into().ok();
|
||||
hnd
|
||||
}),
|
||||
RawDisplayHandle::Xcb(XcbDisplayHandle::new(
|
||||
Some(core::ptr::NonNull::new_unchecked(connection)),
|
||||
screen,
|
||||
)),
|
||||
));
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
|
|
@ -565,10 +591,17 @@ pub mod skia {
|
|||
screen: core::ffi::c_int,
|
||||
) -> CppRawHandleOpaque {
|
||||
use raw_window_handle::{XlibDisplayHandle, XlibWindowHandle};
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::Xlib(init_raw!(XlibWindowHandle { window, visual_id })),
|
||||
RawDisplayHandle::Xlib(init_raw!(XlibDisplayHandle { display, screen })),
|
||||
);
|
||||
let handle = CppRawHandle::from((
|
||||
RawWindowHandle::Xlib({
|
||||
let mut hnd = XlibWindowHandle::new(window);
|
||||
hnd.visual_id = visual_id;
|
||||
hnd
|
||||
}),
|
||||
RawDisplayHandle::Xlib(XlibDisplayHandle::new(
|
||||
Some(core::ptr::NonNull::new_unchecked(display)),
|
||||
screen,
|
||||
)),
|
||||
));
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
|
|
@ -578,23 +611,29 @@ pub mod skia {
|
|||
display: *mut c_void,
|
||||
) -> CppRawHandleOpaque {
|
||||
use raw_window_handle::{WaylandDisplayHandle, WaylandWindowHandle};
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::Wayland(init_raw!(WaylandWindowHandle { surface })),
|
||||
RawDisplayHandle::Wayland(init_raw!(WaylandDisplayHandle { display })),
|
||||
);
|
||||
let handle = CppRawHandle::from((
|
||||
RawWindowHandle::Wayland(WaylandWindowHandle::new(core::ptr::NonNull::new_unchecked(
|
||||
surface,
|
||||
))),
|
||||
RawDisplayHandle::Wayland(WaylandDisplayHandle::new(
|
||||
core::ptr::NonNull::new_unchecked(display),
|
||||
)),
|
||||
));
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_new_raw_window_handle_appkit(
|
||||
ns_view: *mut c_void,
|
||||
ns_window: *mut c_void,
|
||||
_ns_window: *mut c_void,
|
||||
) -> CppRawHandleOpaque {
|
||||
use raw_window_handle::{AppKitDisplayHandle, AppKitWindowHandle};
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::AppKit(init_raw!(AppKitWindowHandle { ns_view, ns_window })),
|
||||
RawDisplayHandle::AppKit(AppKitDisplayHandle::empty()),
|
||||
);
|
||||
let handle = CppRawHandle::from((
|
||||
RawWindowHandle::AppKit(AppKitWindowHandle::new(core::ptr::NonNull::new_unchecked(
|
||||
ns_view,
|
||||
))),
|
||||
RawDisplayHandle::AppKit(AppKitDisplayHandle::new()),
|
||||
));
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
|
|
@ -613,21 +652,10 @@ pub mod skia {
|
|||
) -> SkiaRendererOpaque {
|
||||
let handle = &*(handle_opaque as *const CppRawHandle);
|
||||
|
||||
// Safety: This is safe because the handle remains valid; the next rwh release provides `new()` without unsafe.
|
||||
let active_handle = unsafe { raw_window_handle::ActiveHandle::new_unchecked() };
|
||||
|
||||
// Safety: the C++ code should ensure that the handle is valid
|
||||
let (window_handle, display_handle) = unsafe {
|
||||
(
|
||||
raw_window_handle::WindowHandle::borrow_raw(handle.0, active_handle),
|
||||
raw_window_handle::DisplayHandle::borrow_raw(handle.1),
|
||||
)
|
||||
};
|
||||
|
||||
let boxed_renderer: Box<SkiaRenderer> = Box::new(
|
||||
SkiaRenderer::new(
|
||||
window_handle,
|
||||
display_handle,
|
||||
handle.0.clone(),
|
||||
handle.0.clone(),
|
||||
PhysicalSize { width: size.width, height: size.height },
|
||||
)
|
||||
.unwrap(),
|
||||
|
|
|
|||
|
|
@ -485,7 +485,7 @@ impl EventLoopState {
|
|||
Event::Resumed => ALL_WINDOWS.with(|ws| {
|
||||
for (_, window_weak) in ws.borrow().iter() {
|
||||
if let Some(w) = window_weak.upgrade() {
|
||||
if let Err(e) = w.renderer.resumed(&w.winit_window()) {
|
||||
if let Err(e) = w.renderer.resumed(w.winit_window()) {
|
||||
self.loop_error = Some(e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ pub enum SlintUserEvent {
|
|||
}
|
||||
|
||||
mod renderer {
|
||||
use std::rc::Rc;
|
||||
|
||||
use i_slint_core::platform::PlatformError;
|
||||
|
||||
pub trait WinitCompatibleRenderer {
|
||||
|
|
@ -43,7 +45,7 @@ mod renderer {
|
|||
fn occluded(&self, _: bool) {}
|
||||
|
||||
// Got winit::Event::Resumed
|
||||
fn resumed(&self, _winit_window: &winit::window::Window) -> Result<(), PlatformError> {
|
||||
fn resumed(&self, _winit_window: Rc<winit::window::Window>) -> Result<(), PlatformError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ use std::rc::Rc;
|
|||
|
||||
use crate::winitwindowadapter::physical_size_to_slint;
|
||||
use i_slint_core::platform::PlatformError;
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||
|
||||
pub struct WinitSkiaRenderer {
|
||||
renderer: i_slint_renderer_skia::SkiaRenderer,
|
||||
|
|
@ -13,11 +12,11 @@ pub struct WinitSkiaRenderer {
|
|||
|
||||
impl WinitSkiaRenderer {
|
||||
pub fn new(
|
||||
window_builder: winit::window::WindowBuilder,
|
||||
window_attributes: winit::window::WindowAttributes,
|
||||
) -> Result<(Box<dyn super::WinitCompatibleRenderer>, Rc<winit::window::Window>), PlatformError>
|
||||
{
|
||||
let winit_window = Rc::new(crate::event_loop::with_window_target(|event_loop| {
|
||||
window_builder.build(event_loop.event_loop_target()).map_err(|winit_os_error| {
|
||||
event_loop.create_window(window_attributes).map_err(|winit_os_error| {
|
||||
format!("Error creating native window for Skia rendering: {}", winit_os_error)
|
||||
.into()
|
||||
})
|
||||
|
|
@ -37,11 +36,11 @@ impl WinitSkiaRenderer {
|
|||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
pub fn new_software(
|
||||
window_builder: winit::window::WindowBuilder,
|
||||
window_attributes: winit::window::WindowAttributes,
|
||||
) -> Result<(Box<dyn super::WinitCompatibleRenderer>, Rc<winit::window::Window>), PlatformError>
|
||||
{
|
||||
let winit_window = Rc::new(crate::event_loop::with_window_target(|event_loop| {
|
||||
window_builder.build(event_loop.event_loop_target()).map_err(|winit_os_error| {
|
||||
event_loop.create_window(window_attributes).map_err(|winit_os_error| {
|
||||
format!("Error creating native window for Skia rendering: {}", winit_os_error)
|
||||
.into()
|
||||
})
|
||||
|
|
@ -60,11 +59,11 @@ impl WinitSkiaRenderer {
|
|||
}
|
||||
|
||||
pub fn new_opengl(
|
||||
window_builder: winit::window::WindowBuilder,
|
||||
window_attributes: winit::window::WindowAttributes,
|
||||
) -> Result<(Box<dyn super::WinitCompatibleRenderer>, Rc<winit::window::Window>), PlatformError>
|
||||
{
|
||||
let winit_window = Rc::new(crate::event_loop::with_window_target(|event_loop| {
|
||||
window_builder.build(event_loop.event_loop_target()).map_err(|winit_os_error| {
|
||||
event_loop.create_window(window_attributes).map_err(|winit_os_error| {
|
||||
format!("Error creating native window for Skia rendering: {}", winit_os_error)
|
||||
.into()
|
||||
})
|
||||
|
|
@ -92,29 +91,12 @@ impl super::WinitCompatibleRenderer for WinitSkiaRenderer {
|
|||
&self.renderer
|
||||
}
|
||||
|
||||
fn resumed(&self, winit_window: &winit::window::Window) -> Result<(), PlatformError> {
|
||||
fn resumed(&self, winit_window: Rc<winit::window::Window>) -> Result<(), PlatformError> {
|
||||
let size = winit_window.inner_size();
|
||||
|
||||
// Safety: This is safe because the handle remains valid; the next rwh release provides `new()` without unsafe.
|
||||
let active_handle = unsafe { raw_window_handle::ActiveHandle::new_unchecked() };
|
||||
|
||||
// Safety: API wise we can't guarantee that the window/display handles remain valid, so we
|
||||
// use unsafe here. However the winit window adapter keeps the winit window alive as long as
|
||||
// the renderer.
|
||||
// TODO: remove once winit implements HasWindowHandle/HasDisplayHandle
|
||||
let (window_handle, display_handle) = unsafe {
|
||||
(
|
||||
raw_window_handle::WindowHandle::borrow_raw(
|
||||
winit_window.raw_window_handle(),
|
||||
active_handle,
|
||||
),
|
||||
raw_window_handle::DisplayHandle::borrow_raw(winit_window.raw_display_handle()),
|
||||
)
|
||||
};
|
||||
|
||||
self.renderer.set_window_handle(
|
||||
window_handle,
|
||||
display_handle,
|
||||
winit_window.clone(),
|
||||
winit_window.clone(),
|
||||
physical_size_to_slint(&size),
|
||||
winit_window.scale_factor() as f32,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ impl WinitWindowAdapter {
|
|||
});
|
||||
|
||||
let winit_window = self_rc.winit_window();
|
||||
if let Err(e) = self_rc.renderer.resumed(&winit_window) {
|
||||
if let Err(e) = self_rc.renderer.resumed(winit_window.clone()) {
|
||||
i_slint_core::debug_log!("Error initialing renderer in winit backend with window: {e}");
|
||||
}
|
||||
let id = winit_window.id();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
use i_slint_core::api::PhysicalSize as PhysicalWindowSize;
|
||||
use i_slint_core::platform::PlatformError;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use windows::core::Interface;
|
||||
use windows::Win32::Graphics::Direct3D::D3D_FEATURE_LEVEL_11_0;
|
||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN;
|
||||
|
|
@ -245,8 +246,8 @@ pub struct D3DSurface {
|
|||
|
||||
impl super::Surface for D3DSurface {
|
||||
fn new(
|
||||
window_handle: raw_window_handle::WindowHandle<'_>,
|
||||
_display_handle: raw_window_handle::DisplayHandle<'_>,
|
||||
window_handle: Rc<dyn raw_window_handle::HasWindowHandle>,
|
||||
_display_handle: Rc<dyn raw_window_handle::HasDisplayHandle>,
|
||||
size: PhysicalWindowSize,
|
||||
) -> Result<Self, i_slint_core::platform::PlatformError> {
|
||||
let factory_flags = 0;
|
||||
|
|
@ -357,6 +358,10 @@ impl super::Surface for D3DSurface {
|
|||
let gr_context = unsafe { skia_safe::gpu::DirectContext::new_d3d(&backend_context, None) }
|
||||
.ok_or_else(|| format!("unable to create Skia D3D DirectContext"))?;
|
||||
|
||||
let window_handle = window_handle
|
||||
.window_handle()
|
||||
.map_err(|e| format!("error obtaining window handle for skia d3d renderer: {e}"))?;
|
||||
|
||||
let swap_chain = RefCell::new(SwapChain::new(
|
||||
queue,
|
||||
&device,
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ cfg_if::cfg_if! {
|
|||
}
|
||||
|
||||
fn create_default_surface(
|
||||
window_handle: raw_window_handle::WindowHandle<'_>,
|
||||
display_handle: raw_window_handle::DisplayHandle<'_>,
|
||||
window_handle: Rc<dyn raw_window_handle::HasWindowHandle>,
|
||||
display_handle: Rc<dyn raw_window_handle::HasDisplayHandle>,
|
||||
size: PhysicalWindowSize,
|
||||
) -> Result<Box<dyn Surface>, PlatformError> {
|
||||
match DefaultSurface::new(window_handle.clone(), display_handle.clone(), size) {
|
||||
|
|
@ -94,8 +94,8 @@ pub struct SkiaRenderer {
|
|||
rendering_first_time: Cell<bool>,
|
||||
surface: RefCell<Option<Box<dyn Surface>>>,
|
||||
surface_factory: fn(
|
||||
window_handle: raw_window_handle::WindowHandle<'_>,
|
||||
display_handle: raw_window_handle::DisplayHandle<'_>,
|
||||
window_handle: Rc<dyn raw_window_handle::HasWindowHandle>,
|
||||
display_handle: Rc<dyn raw_window_handle::HasDisplayHandle>,
|
||||
size: PhysicalWindowSize,
|
||||
) -> Result<Box<dyn Surface>, PlatformError>,
|
||||
pre_present_callback: RefCell<Option<Box<dyn FnMut()>>>,
|
||||
|
|
@ -157,8 +157,8 @@ impl SkiaRenderer {
|
|||
|
||||
/// Creates a new renderer is associated with the provided window adapter.
|
||||
pub fn new(
|
||||
window_handle: raw_window_handle::WindowHandle<'_>,
|
||||
display_handle: raw_window_handle::DisplayHandle<'_>,
|
||||
window_handle: Rc<dyn raw_window_handle::HasWindowHandle>,
|
||||
display_handle: Rc<dyn raw_window_handle::HasDisplayHandle>,
|
||||
size: PhysicalWindowSize,
|
||||
) -> Result<Self, PlatformError> {
|
||||
Ok(Self::new_with_surface(create_default_surface(window_handle, display_handle, size)?))
|
||||
|
|
@ -192,8 +192,8 @@ impl SkiaRenderer {
|
|||
/// Reset the surface to the window given the window handle
|
||||
pub fn set_window_handle(
|
||||
&self,
|
||||
window_handle: raw_window_handle::WindowHandle<'_>,
|
||||
display_handle: raw_window_handle::DisplayHandle<'_>,
|
||||
window_handle: Rc<dyn raw_window_handle::HasWindowHandle>,
|
||||
display_handle: Rc<dyn raw_window_handle::HasDisplayHandle>,
|
||||
size: PhysicalWindowSize,
|
||||
scale_factor: f32,
|
||||
) -> Result<(), PlatformError> {
|
||||
|
|
@ -547,8 +547,8 @@ impl Drop for SkiaRenderer {
|
|||
pub trait Surface {
|
||||
/// Creates a new surface with the given window, display, and size.
|
||||
fn new(
|
||||
window_handle: raw_window_handle::WindowHandle<'_>,
|
||||
display_handle: raw_window_handle::DisplayHandle<'_>,
|
||||
window_handle: Rc<dyn raw_window_handle::HasWindowHandle>,
|
||||
display_handle: Rc<dyn raw_window_handle::HasDisplayHandle>,
|
||||
size: PhysicalWindowSize,
|
||||
) -> Result<Self, PlatformError>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ use i_slint_core::api::PhysicalSize as PhysicalWindowSize;
|
|||
use metal::MTLPixelFormat;
|
||||
use objc::{rc::autoreleasepool, runtime::YES};
|
||||
|
||||
use raw_window_handle::HasRawWindowHandle;
|
||||
use skia_safe::gpu::mtl;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// This surface renders into the given window using Metal. The provided display argument
|
||||
/// is ignored, as it has no meaning on macOS.
|
||||
|
|
@ -23,8 +23,8 @@ pub struct MetalSurface {
|
|||
|
||||
impl super::Surface for MetalSurface {
|
||||
fn new(
|
||||
window_handle: raw_window_handle::WindowHandle<'_>,
|
||||
_display_handle: raw_window_handle::DisplayHandle<'_>,
|
||||
window_handle: Rc<dyn raw_window_handle::HasWindowHandle>,
|
||||
_display_handle: Rc<dyn raw_window_handle::HasDisplayHandle>,
|
||||
size: PhysicalWindowSize,
|
||||
) -> Result<Self, i_slint_core::platform::PlatformError> {
|
||||
let device = metal::Device::system_default()
|
||||
|
|
@ -39,10 +39,14 @@ impl super::Surface for MetalSurface {
|
|||
layer.set_drawable_size(CGSize::new(size.width as f64, size.height as f64));
|
||||
|
||||
unsafe {
|
||||
let view = match window_handle.raw_window_handle() {
|
||||
let view = match window_handle
|
||||
.window_handle()
|
||||
.map_err(|e| format!("Error obtaining window handle for skia metal renderer: {e}"))?
|
||||
.as_raw()
|
||||
{
|
||||
raw_window_handle::RawWindowHandle::AppKit(
|
||||
raw_window_handle::AppKitWindowHandle { ns_view, .. },
|
||||
) => ns_view,
|
||||
) => ns_view.as_ptr(),
|
||||
_ => {
|
||||
return Err("Skia Renderer: Metal surface is only supported with AppKit".into())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
use std::{cell::RefCell, num::NonZeroU32};
|
||||
use std::cell::RefCell;
|
||||
use std::num::NonZeroU32;
|
||||
use std::rc::Rc;
|
||||
|
||||
use glutin::{
|
||||
config::GetGlConfig,
|
||||
|
|
@ -24,8 +26,8 @@ pub struct OpenGLSurface {
|
|||
|
||||
impl super::Surface for OpenGLSurface {
|
||||
fn new(
|
||||
window_handle: raw_window_handle::WindowHandle<'_>,
|
||||
display_handle: raw_window_handle::DisplayHandle<'_>,
|
||||
window_handle: Rc<dyn raw_window_handle::HasWindowHandle>,
|
||||
display_handle: Rc<dyn raw_window_handle::HasDisplayHandle>,
|
||||
size: PhysicalWindowSize,
|
||||
) -> Result<Self, PlatformError> {
|
||||
let width: std::num::NonZeroU32 = size.width.try_into().map_err(|_| {
|
||||
|
|
@ -35,6 +37,13 @@ impl super::Surface for OpenGLSurface {
|
|||
format!("Attempting to create window surface with an invalid height: {}", size.height)
|
||||
})?;
|
||||
|
||||
let window_handle = window_handle
|
||||
.window_handle()
|
||||
.map_err(|e| format!("error obtaining window handle for skia opengl renderer: {e}"))?;
|
||||
let display_handle = display_handle
|
||||
.display_handle()
|
||||
.map_err(|e| format!("error obtaining display handle for skia opengl renderer: {e}"))?;
|
||||
|
||||
let (current_glutin_context, glutin_surface) =
|
||||
Self::init_glutin(window_handle, display_handle, width, height)?;
|
||||
|
||||
|
|
@ -220,17 +229,14 @@ impl OpenGLSurface {
|
|||
}
|
||||
|
||||
let gl_display = unsafe {
|
||||
glutin::display::Display::new(
|
||||
_display_handle.as_raw(),
|
||||
display_api_preference,
|
||||
)
|
||||
.map_err(|glutin_error| {
|
||||
format!(
|
||||
"Error creating glutin display for native display {:#?}: {}",
|
||||
_display_handle.as_raw(),
|
||||
glutin_error
|
||||
)
|
||||
})?
|
||||
glutin::display::Display::new(_display_handle.as_raw(), display_api_preference)
|
||||
.map_err(|glutin_error| {
|
||||
format!(
|
||||
"Error creating glutin display for native display {:#?}: {}",
|
||||
_display_handle.as_raw(),
|
||||
glutin_error
|
||||
)
|
||||
})?
|
||||
};
|
||||
|
||||
let config_template_builder = glutin::config::ConfigTemplateBuilder::new();
|
||||
|
|
@ -315,10 +321,10 @@ impl OpenGLSurface {
|
|||
if let raw_window_handle::RawWindowHandle::AppKit(raw_window_handle::AppKitWindowHandle {
|
||||
ns_view,
|
||||
..
|
||||
}) = _window_handle.raw_window_handle()
|
||||
}) = _window_handle.as_raw()
|
||||
{
|
||||
use cocoa::appkit::NSView;
|
||||
let view_id: cocoa::base::id = ns_view as *const _ as *mut _;
|
||||
let view_id: cocoa::base::id = ns_view.as_ptr() as *const _ as *mut _;
|
||||
unsafe {
|
||||
NSView::setLayerContentsPlacement(view_id, cocoa::appkit::NSViewLayerContentsPlacement::NSViewLayerContentsPlacementTopLeft)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
use i_slint_core::api::PhysicalSize as PhysicalWindowSize;
|
||||
|
||||
use std::{cell::RefCell, num::NonZeroU32};
|
||||
use std::cell::RefCell;
|
||||
use std::num::NonZeroU32;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub trait RenderBuffer {
|
||||
fn with_buffer(
|
||||
|
|
@ -20,8 +22,13 @@ pub trait RenderBuffer {
|
|||
}
|
||||
|
||||
struct SoftbufferRenderBuffer {
|
||||
_context: softbuffer::Context,
|
||||
surface: RefCell<softbuffer::Surface>,
|
||||
_context: softbuffer::Context<Rc<dyn raw_window_handle::HasDisplayHandle>>,
|
||||
surface: RefCell<
|
||||
softbuffer::Surface<
|
||||
Rc<dyn raw_window_handle::HasDisplayHandle>,
|
||||
Rc<dyn raw_window_handle::HasWindowHandle>,
|
||||
>,
|
||||
>,
|
||||
}
|
||||
|
||||
impl RenderBuffer for SoftbufferRenderBuffer {
|
||||
|
|
@ -74,18 +81,17 @@ pub struct SoftwareSurface {
|
|||
|
||||
impl super::Surface for SoftwareSurface {
|
||||
fn new(
|
||||
window_handle: raw_window_handle::WindowHandle<'_>,
|
||||
display_handle: raw_window_handle::DisplayHandle<'_>,
|
||||
window_handle: Rc<dyn raw_window_handle::HasWindowHandle>,
|
||||
display_handle: Rc<dyn raw_window_handle::HasDisplayHandle>,
|
||||
_size: PhysicalWindowSize,
|
||||
) -> Result<Self, i_slint_core::platform::PlatformError> {
|
||||
let _context = unsafe {
|
||||
softbuffer::Context::new(&display_handle)
|
||||
.map_err(|e| format!("Error creating softbuffer context: {e}"))?
|
||||
};
|
||||
let _context = softbuffer::Context::new(display_handle)
|
||||
.map_err(|e| format!("Error creating softbuffer context: {e}"))?;
|
||||
|
||||
let surface = unsafe { softbuffer::Surface::new(&_context, &window_handle) }.map_err(
|
||||
|softbuffer_error| format!("Error creating softbuffer surface: {}", softbuffer_error),
|
||||
)?;
|
||||
let surface =
|
||||
softbuffer::Surface::new(&_context, window_handle).map_err(|softbuffer_error| {
|
||||
format!("Error creating softbuffer surface: {}", softbuffer_error)
|
||||
})?;
|
||||
|
||||
let surface_access =
|
||||
Box::new(SoftbufferRenderBuffer { _context, surface: RefCell::new(surface) });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue