Add Metal support to the C API

This commit is contained in:
Patrick Walton 2019-06-21 13:37:17 -07:00
parent 1c34b12948
commit 2c49a3360e
4 changed files with 88 additions and 1 deletions

3
Cargo.lock generated
View File

@ -1398,13 +1398,16 @@ version = "0.1.0"
dependencies = [ dependencies = [
"cbindgen 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", "cbindgen 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)",
"font-kit 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "font-kit 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_canvas 0.1.0", "pathfinder_canvas 0.1.0",
"pathfinder_content 0.1.0", "pathfinder_content 0.1.0",
"pathfinder_geometry 0.3.0", "pathfinder_geometry 0.3.0",
"pathfinder_gl 0.1.0", "pathfinder_gl 0.1.0",
"pathfinder_gpu 0.1.0", "pathfinder_gpu 0.1.0",
"pathfinder_metal 0.1.0",
"pathfinder_renderer 0.1.0", "pathfinder_renderer 0.1.0",
"pathfinder_simd 0.3.0", "pathfinder_simd 0.3.0",
] ]

View File

@ -10,6 +10,7 @@ crate-type = ["staticlib"]
[dependencies] [dependencies]
font-kit = "0.2" font-kit = "0.2"
foreign-types = "0.3"
gl = "0.6" gl = "0.6"
libc = "0.2" libc = "0.2"
@ -34,5 +35,11 @@ path = "../renderer"
[dependencies.pathfinder_simd] [dependencies.pathfinder_simd]
path = "../simd" path = "../simd"
[target.'cfg(target_os = "macos")'.dependencies]
metal = "0.14"
[target.'cfg(target_os = "macos")'.dependencies.pathfinder_metal]
path = "../metal"
[build-dependencies] [build-dependencies]
cbindgen = "0.8" cbindgen = "0.8"

View File

@ -11,6 +11,7 @@
//! C bindings to Pathfinder. //! C bindings to Pathfinder.
use font_kit::handle::Handle; use font_kit::handle::Handle;
use foreign_types::ForeignTypeRef;
use gl; use gl;
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, FillStyle, LineJoin}; use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, FillStyle, LineJoin};
use pathfinder_canvas::{Path2D, TextMetrics}; use pathfinder_canvas::{Path2D, TextMetrics};
@ -33,6 +34,11 @@ use std::os::raw::{c_char, c_void};
use std::slice; use std::slice;
use std::str; use std::str;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use metal::{CAMetalLayer, CoreAnimationLayerRef};
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use pathfinder_metal::MetalDevice;
// Constants // Constants
// `canvas` // `canvas`
@ -118,10 +124,18 @@ pub type PFGLFunctionLoader = extern "C" fn(name: *const c_char, userdata: *mut
// `gpu` // `gpu`
pub type PFGLDestFramebufferRef = *mut DestFramebuffer<GLDevice>; pub type PFGLDestFramebufferRef = *mut DestFramebuffer<GLDevice>;
pub type PFGLRendererRef = *mut Renderer<GLDevice>; pub type PFGLRendererRef = *mut Renderer<GLDevice>;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
pub type PFMetalDestFramebufferRef = *mut DestFramebuffer<MetalDevice>;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
pub type PFMetalRendererRef = *mut Renderer<MetalDevice>;
// FIXME(pcwalton): Double-boxing is unfortunate. Remove this when `std::raw::TraitObject` is // FIXME(pcwalton): Double-boxing is unfortunate. Remove this when `std::raw::TraitObject` is
// stable? // stable?
pub type PFResourceLoaderRef = *mut Box<dyn ResourceLoader>; pub type PFResourceLoaderRef = *mut Box<dyn ResourceLoader>;
// `metal`
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
pub type PFMetalDeviceRef = *mut MetalDevice;
// `renderer` // `renderer`
pub type PFSceneRef = *mut Scene; pub type PFSceneRef = *mut Scene;
pub type PFSceneProxyRef = *mut SceneProxy; pub type PFSceneProxyRef = *mut SceneProxy;
@ -456,6 +470,46 @@ pub unsafe extern "C" fn PFGLRendererGetDevice(renderer: PFGLRendererRef) -> PFG
&mut (*renderer).device &mut (*renderer).device
} }
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalDestFramebufferCreateFullWindow(window_size: *const PFVector2I)
-> PFMetalDestFramebufferRef {
Box::into_raw(Box::new(DestFramebuffer::full_window((*window_size).to_rust())))
}
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalDestFramebufferDestroy(dest_framebuffer:
PFMetalDestFramebufferRef) {
drop(Box::from_raw(dest_framebuffer))
}
/// Takes ownership of `device` and `dest_framebuffer`, but not `resources`.
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalRendererCreate(device: PFMetalDeviceRef,
resources: PFResourceLoaderRef,
dest_framebuffer: PFMetalDestFramebufferRef,
options: *const PFRendererOptions)
-> PFMetalRendererRef {
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
&**resources,
*Box::from_raw(dest_framebuffer),
(*options).to_rust())))
}
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalRendererDestroy(renderer: PFMetalRendererRef) {
drop(Box::from_raw(renderer))
}
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalRendererGetDevice(renderer: PFMetalRendererRef) -> PFMetalDeviceRef {
&mut (*renderer).device
}
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFSceneProxyBuildAndRenderGL(scene_proxy: PFSceneProxyRef, pub unsafe extern "C" fn PFSceneProxyBuildAndRenderGL(scene_proxy: PFSceneProxyRef,
renderer: PFGLRendererRef, renderer: PFGLRendererRef,
@ -463,6 +517,29 @@ pub unsafe extern "C" fn PFSceneProxyBuildAndRenderGL(scene_proxy: PFSceneProxyR
(*scene_proxy).build_and_render(&mut *renderer, (*build_options).to_rust()) (*scene_proxy).build_and_render(&mut *renderer, (*build_options).to_rust())
} }
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFSceneProxyBuildAndRenderMetal(scene_proxy: PFSceneProxyRef,
renderer: PFMetalRendererRef,
build_options: *const PFBuildOptions) {
(*scene_proxy).build_and_render(&mut *renderer, (*build_options).to_rust())
}
// `metal`
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalDeviceCreate(layer: *mut CAMetalLayer)
-> PFMetalDeviceRef {
Box::into_raw(Box::new(MetalDevice::new(CoreAnimationLayerRef::from_ptr(layer))))
}
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
#[no_mangle]
pub unsafe extern "C" fn PFMetalDeviceDestroy(device: PFMetalDeviceRef) {
drop(Box::from_raw(device))
}
// `renderer` // `renderer`
#[no_mangle] #[no_mangle]

View File

@ -15,7 +15,7 @@ UNAME=$(shell uname -s)
ifeq ($(UNAME),Darwin) ifeq ($(UNAME),Darwin)
# FIXME(pcwalton): Don't link against HarfBuzz!! # FIXME(pcwalton): Don't link against HarfBuzz!!
LIBS+=-framework OpenGL -framework CoreFoundation -framework CoreGraphics -framework CoreText LIBS+=-framework OpenGL -framework CoreFoundation -framework CoreGraphics -framework CoreText
LIBS+=-lharfbuzz LIBS+=-framework Metal -lharfbuzz
else else
LIBS+=-lGL LIBS+=-lGL
endif endif