Skip to content

Commit

Permalink
Auto merge of rust-windowing#378 - pcwalton:macos-fixes, r=pcwalton
Browse files Browse the repository at this point in the history
Fix Metal memory management and the `canvas_metal_minimal`, `canvas_nanovg`, and `macos_app` examples.

`winit` does not create an autorelease pool, so the Metal backend had not taken
the presence of one into account. Now the Metal backend creates and flushes
autorelease pools as necessary.

Closes rust-windowing#334.
Closes rust-windowing#376.
  • Loading branch information
bors-servo authored Jun 29, 2020
2 parents ac405fb + 42289ee commit c6e7ed0
Show file tree
Hide file tree
Showing 23 changed files with 268 additions and 169 deletions.
42 changes: 37 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion c/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ path = "../simd"
path = "../svg"

[target.'cfg(target_os = "macos")'.dependencies]
metal = "0.17"
core-foundation = "0.6"
io-surface = "0.12"
metal = "0.18"

[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
path = "../metal"
Expand Down
4 changes: 4 additions & 0 deletions c/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,26 @@ include = [
"pathfinder_gpu",
"pathfinder_metal",
"pathfinder_renderer",
"pathfinder_svg",
]

[export.rename]
"BuildOptions" = "PFBuildOptionsPrivate"
"CanvasFontContext" = "PFCanvasFontContextPrivate"
"CanvasRenderingContext2D" = "PFCanvasRenderingContext2DPrivate"
"CoreAnimationDrawableRef" = "NSObject<CAMetalDrawable>"
"DestFramebuffer_GLDevice" = "PFDestFramebufferGLDevicePrivate"
"DestFramebuffer_MetalDevice" = "PFDestFramebufferMetalDevicePrivate"
"FillStyle" = "PFFillStylePrivate"
"GLDevice" = "PFGLDevicePrivate"
"Handle" = "FKHandlePrivate"
"MetalDevice" = "PFMetalDevicePrivate"
"NativeMetalDeviceRef" = "NSObject<MTLDevice>"
"Path2D" = "PFPath2DPrivate"
"RenderTransform" = "PFRenderTransformPrivate"
"Renderer_GLDevice" = "PFRendererGLDevicePrivate"
"Renderer_MetalDevice" = "PFRendererMetalDevicePrivate"
"ResourceLoaderWrapper" = "PFResourceLoaderWrapperPrivate"
"Scene" = "PFScenePrivate"
"SceneProxy" = "PFSceneProxyPrivate"
"SVGScene" = "PFSVGScenePrivate"
45 changes: 36 additions & 9 deletions c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ use std::str;
use usvg::{Options, Tree};

#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use metal::{self, CAMetalLayer, CoreAnimationLayerRef};
use io_surface::IOSurfaceRef;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use pathfinder_metal::MetalDevice;
use metal::{self, CoreAnimationDrawableRef, DeviceRef as NativeMetalDeviceRef};
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use foreign_types::ForeignTypeRef;
use pathfinder_metal::MetalDevice;

// Constants

Expand Down Expand Up @@ -660,12 +660,39 @@ pub unsafe extern "C" fn PFSceneProxyBuildAndRenderMetal(scene_proxy: PFScenePro

#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalDeviceCreate(layer: *mut CAMetalLayer)
-> PFMetalDeviceRef {
let device =
metal::Device::system_default().expect("Failed to get Metal system default device!");
let layer = CoreAnimationLayerRef::from_ptr(layer);
Box::into_raw(Box::new(MetalDevice::new(device, layer.next_drawable().unwrap())))
pub unsafe extern "C" fn PFMetalDeviceCreateWithIOSurface(metal_device: &NativeMetalDeviceRef,
io_surface: IOSurfaceRef)
-> PFMetalDeviceRef {
Box::into_raw(Box::new(MetalDevice::new(metal_device, io_surface)))
}

#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalDeviceCreateWithDrawable(metal_device: &NativeMetalDeviceRef,
ca_drawable: &CoreAnimationDrawableRef)
-> PFMetalDeviceRef {
Box::into_raw(Box::new(MetalDevice::new(metal_device, ca_drawable)))
}

#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalDeviceSwapIOSurface(device: PFMetalDeviceRef,
new_io_surface: IOSurfaceRef) {
drop((*device).swap_texture(new_io_surface))
}

#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalDeviceSwapDrawable(device: PFMetalDeviceRef,
new_ca_drawable: &CoreAnimationDrawableRef) {
drop((*device).swap_texture(new_ca_drawable))
}

#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalDevicePresentDrawable(device: PFMetalDeviceRef,
ca_drawable: &CoreAnimationDrawableRef) {
(*device).present_drawable(ca_drawable)
}

#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
Expand Down
2 changes: 1 addition & 1 deletion demo/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ path = "../../svg"
path = "../../ui"

[target.'cfg(target_os = "macos")'.dependencies]
metal = "0.17"
metal = "0.18"

[target.'cfg(target_os = "macos")'.dependencies.io-surface]
version = "0.12"
Expand Down
2 changes: 1 addition & 1 deletion demo/native/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ version = "<0.19.4" # 0.19.4 causes build errors https://github.com/rust-windowi
[target.'cfg(target_os = "macos")'.dependencies]
foreign-types = "0.3"
io-surface = "0.12"
metal = "0.17"
metal = "0.18"
objc = "0.2"

[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
Expand Down
6 changes: 5 additions & 1 deletion demo/native/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use pathfinder_resources::ResourceLoader;
use pathfinder_resources::fs::FilesystemResourceLoader;
use std::cell::Cell;
use std::collections::VecDeque;
use std::mem;
use std::path::PathBuf;
use std::sync::Mutex;
use surfman::{SurfaceAccess, SurfaceType, declare_surfman};
Expand Down Expand Up @@ -160,7 +161,10 @@ impl Window for WindowImpl {

#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
fn metal_device(&self) -> metal::Device {
self.metal_device.0.clone()
// FIXME(pcwalton): Remove once `surfman` upgrades `metal-rs` version.
unsafe {
mem::transmute(self.metal_device.0.clone())
}
}

#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
Expand Down
2 changes: 1 addition & 1 deletion examples/canvas_metal_minimal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2018"
[dependencies]
foreign-types = "0.3"
gl = "0.14"
metal = "0.17"
metal = "0.18"
objc = "0.2"
sdl2 = "0.33"
sdl2-sys = "0.33"
Expand Down
8 changes: 6 additions & 2 deletions examples/canvas_metal_minimal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ fn main() {
let metal_layer = unsafe {
CoreAnimationLayerRef::from_ptr(SDL_RenderGetMetalLayer(canvas.raw()) as *mut CAMetalLayer)
};
let metal_device = metal_layer.device();
let drawable = metal_layer.next_drawable().unwrap();

// Create a Pathfinder renderer.
let device = MetalDevice::new(metal_layer);
let device = unsafe {
MetalDevice::new(metal_device, drawable.clone())
};
let mode = RendererMode::default_for_device(&device);
let options = RendererOptions {
dest: DestFramebuffer::full_window(window_size),
Expand Down Expand Up @@ -81,7 +85,7 @@ fn main() {
renderer.mode().level,
RayonExecutor);
scene.build_and_render(&mut renderer, BuildOptions::default());
renderer.device().present_drawable();
renderer.device().present_drawable(drawable);

// Wait for a keypress.
let mut event_pump = sdl_context.event_pump().unwrap();
Expand Down
10 changes: 6 additions & 4 deletions examples/canvas_nanovg/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use pathfinder_geometry::vector::{Vector2F, vec2f, vec2i};
use pathfinder_gl::{GLDevice, GLVersion};
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererMode, RendererOptions};
use pathfinder_renderer::gpu::renderer::Renderer;
use pathfinder_renderer::options::BuildOptions;
use pathfinder_resources::ResourceLoader;
Expand Down Expand Up @@ -1517,13 +1517,15 @@ fn main() {
let pathfinder_device = GLDevice::new(GLVersion::GL3, default_framebuffer);

// Create a Pathfinder renderer.
let renderer_mode = RendererMode::default_for_device(&pathfinder_device);
let renderer_options = RendererOptions {
background_color: Some(rgbf(0.3, 0.3, 0.32)),
..RendererOptions::default_for_device(&pathfinder_device)
dest: DestFramebuffer::full_window(framebuffer_size),
..RendererOptions::default()
};
let mut renderer = Renderer::new(pathfinder_device,
&resources,
DestFramebuffer::full_window(framebuffer_size),
renderer_mode,
renderer_options);

// Initialize font state.
Expand Down Expand Up @@ -1568,7 +1570,7 @@ fn main() {
// Render the canvas to screen.
let canvas = context.into_canvas();
let mut scene = SceneProxy::from_scene(canvas.into_scene(),
renderer.level(),
renderer.mode().level,
RayonExecutor);
scene.build_and_render(&mut renderer, BuildOptions::default());

Expand Down
12 changes: 6 additions & 6 deletions examples/macos_app/Pathfinder Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
6A9A35B322C1E14700B86652 /* libpathfinder_c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A9A35B222C1E14700B86652 /* libpathfinder_c.a */; };
6A7C3B7224A6B75500027B8E /* libpathfinder_c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A7C3B7124A6B75500027B8E /* libpathfinder_c.a */; };
6AFD6FFA22BD780D00AC1ED3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AFD6FF922BD780D00AC1ED3 /* AppDelegate.m */; };
6AFD6FFC22BD781000AC1ED3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6AFD6FFB22BD781000AC1ED3 /* Assets.xcassets */; };
6AFD6FFF22BD781000AC1ED3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6AFD6FFD22BD781000AC1ED3 /* MainMenu.xib */; };
Expand All @@ -17,7 +17,7 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
6A9A35B222C1E14700B86652 /* libpathfinder_c.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpathfinder_c.a; path = ../../../target/release/libpathfinder_c.a; sourceTree = "<group>"; };
6A7C3B7124A6B75500027B8E /* libpathfinder_c.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpathfinder_c.a; path = ../../../target/release/libpathfinder_c.a; sourceTree = "<group>"; };
6AFD6FF522BD780D00AC1ED3 /* Pathfinder Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Pathfinder Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
6AFD6FF822BD780D00AC1ED3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
6AFD6FF922BD780D00AC1ED3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
Expand All @@ -36,7 +36,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6A9A35B322C1E14700B86652 /* libpathfinder_c.a in Frameworks */,
6A7C3B7224A6B75500027B8E /* libpathfinder_c.a in Frameworks */,
6AFD700F22BD930500AC1ED3 /* libharfbuzz.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -72,7 +72,7 @@
6AFD700A22BD7B7A00AC1ED3 /* PathfinderView.m */,
6AFD700122BD781000AC1ED3 /* main.m */,
6AFD700322BD781000AC1ED3 /* Pathfinder_Example.entitlements */,
6A9A35B222C1E14700B86652 /* libpathfinder_c.a */,
6A7C3B7124A6B75500027B8E /* libpathfinder_c.a */,
6AFD700E22BD930500AC1ED3 /* libharfbuzz.a */,
);
path = "Pathfinder Example";
Expand Down Expand Up @@ -290,7 +290,7 @@
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = "";
HEADER_SEARCH_PATHS = ../../c/build/include;
HEADER_SEARCH_PATHS = ../../target/release;
INFOPLIST_FILE = "Pathfinder Example/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -312,7 +312,7 @@
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = "";
HEADER_SEARCH_PATHS = ../../c/build/include;
HEADER_SEARCH_PATHS = ../../target/release;
INFOPLIST_FILE = "Pathfinder Example/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down
Loading

0 comments on commit c6e7ed0

Please sign in to comment.