Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-renderer/src/platform/mac/rendering/wgpu/mod.rs
1mod renderer;
2mod renderer_manager;
3 
4use crate::rendering::wgpu::Resources;
5use crate::{platform::mac::rendering::Device, rendering::GPUPowerPreference};
6use anyhow::{anyhow, Result};
7pub use renderer_manager::RendererManager;
8 
9use crate::rendering::OnGPUDeviceSelected;
10use cocoa::{appkit::NSView, base::id};
11use pathfinder_geometry::vector::vec2f;
12use std::ptr::NonNull;
13use wgpu::rwh::{
14 AppKitDisplayHandle, AppKitWindowHandle, DisplayHandle, HandleError, HasDisplayHandle,
15 HasWindowHandle, RawDisplayHandle, RawWindowHandle, WindowHandle,
16};
17 
18impl Device {
19 /// Constructs a new [`Device`] to render using WGPU.
20 pub fn new_wgpu(
21 native_view: id,
22 gpu_power_preference: GPUPowerPreference,
23 on_gpu_device_info: Box<OnGPUDeviceSelected>,
24 ) -> Result<Device> {
25 let view_frame = unsafe { NSView::frame(native_view) };
26 let surface_size = vec2f(view_frame.size.width as f32, view_frame.size.height as f32);
27 
28 let appkit_window_handle = AppKitWindowHandle::new(
29 NonNull::new(native_view)
30 .ok_or_else(|| anyhow!("Received null NSView pointer"))?
31 .cast(),
32 );
33 let window_handle =
34 unsafe { WindowHandle::borrow_raw(RawWindowHandle::AppKit(appkit_window_handle)) };
35 let display_handle = unsafe {
36 DisplayHandle::borrow_raw(RawDisplayHandle::AppKit(AppKitDisplayHandle::new()))
37 };
38 
39 let trusted_window = TrustedWindow {
40 window_handle,
41 display_handle,
42 };
43 
44 crate::rendering::wgpu::init_wgpu_instance(Box::new(trusted_window));
45 
46 let resources = Resources::new(
47 trusted_window,
48 gpu_power_preference,
49 None,
50 &on_gpu_device_info,
51 surface_size,
52 false, /* downrank_non_nvidia_vulkan_adapters */
53 )?;
54 Ok(Device::WGPU(Box::new(resources)))
55 }
56}
57 
58/// Wrapper struct that implements the [`HasRawWindowHandle`] and [`HasRawDisplayHandle`] traits.
59/// The raw-window-handle crate purposefully does not provide a blanket implementation of this trait
60/// for any implementation of [`RawWindowHandle`] or [`RawDisplayHandle`] because it's not
61/// guaranteed that the underlying window won't become invalid while the `WindowHandle` is alive.
62/// In the case of Warp this _should_ be safe because we ultimately deallocate the native window
63/// when [`crate::platform::mac::Window`] is deallocated (once a `Window` is deallocated, there
64/// are no pointers to the native window anymore, which cause it to be deallocated via the
65/// `warp_dealloc_window` callback).
66/// See <https://github.com/rust-windowing/raw-window-handle/pull/73> for more information on the
67/// safety requirements of implementing the [`HasRawWindowHandle`] trait.
68#[derive(Copy, Clone, Debug)]
69struct TrustedWindow {
70 window_handle: WindowHandle<'static>,
71 display_handle: DisplayHandle<'static>,
72}
73 
74// THIS IS INCREDIBLY UNSAFE!!! DO NOT DO THIS!!!
75//
76// That said, we're not using this codepath in production, and it unblocks us
77// moving to wgpu 0.19 (an important migration for the Linux target), so we're
78// doing this and covering our eyes for now, with the intention of fixing it or
79// removing support for `wpgu` in our macOS backend.
80unsafe impl Send for TrustedWindow {}
81unsafe impl Sync for TrustedWindow {}
82 
83impl HasWindowHandle for TrustedWindow {
84 fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
85 Ok(self.window_handle)
86 }
87}
88 
89impl HasDisplayHandle for TrustedWindow {
90 fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
91 Ok(self.display_handle)
92 }
93}
94