Update the C backend

This commit is contained in:
Patrick Walton 2020-06-23 13:08:34 -07:00
parent 7a1db16340
commit 72cdef2c2a
1 changed files with 57 additions and 22 deletions

View File

@ -23,11 +23,13 @@ use pathfinder_geometry::transform2d::{Matrix2x2F, Transform2F};
use pathfinder_geometry::transform3d::{Perspective, Transform4F}; use pathfinder_geometry::transform3d::{Perspective, Transform4F};
use pathfinder_geometry::vector::{Vector2F, Vector2I}; use pathfinder_geometry::vector::{Vector2F, Vector2I};
use pathfinder_gl::{GLDevice, GLVersion}; use pathfinder_gl::{GLDevice, GLVersion};
use pathfinder_gpu::Device;
use pathfinder_resources::ResourceLoader; use pathfinder_resources::ResourceLoader;
use pathfinder_resources::fs::FilesystemResourceLoader; use pathfinder_resources::fs::FilesystemResourceLoader;
use pathfinder_renderer::concurrent::rayon::RayonExecutor; use pathfinder_renderer::concurrent::rayon::RayonExecutor;
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy; use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions}; use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererLevel};
use pathfinder_renderer::gpu::options::{RendererMode, RendererOptions};
use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::gpu::renderer::Renderer;
use pathfinder_renderer::options::{BuildOptions, RenderTransform}; use pathfinder_renderer::options::{BuildOptions, RenderTransform};
use pathfinder_renderer::scene::Scene; use pathfinder_renderer::scene::Scene;
@ -39,7 +41,7 @@ use std::slice;
use std::str; use std::str;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))] #[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use metal::{CAMetalLayer, CoreAnimationLayerRef, Device}; use metal::{self, CAMetalLayer, CoreAnimationLayerRef};
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))] #[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use pathfinder_metal::MetalDevice; use pathfinder_metal::MetalDevice;
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))] #[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
@ -74,6 +76,10 @@ pub const PF_GL_VERSION_GLES3: u8 = 1;
// `renderer` // `renderer`
pub const PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR: u8 = 0x1; pub const PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR: u8 = 0x1;
pub const PF_RENDERER_OPTIONS_FLAGS_SHOW_DEBUG_UI: u8 = 0x2;
pub const PF_RENDERER_LEVEL_D3D9: u8 = 0x1;
pub const PF_RENDERER_LEVEL_D3D11: u8 = 0x2;
// Types // Types
@ -182,13 +188,20 @@ pub type PFMetalDeviceRef = *mut MetalDevice;
pub type PFSceneRef = *mut Scene; pub type PFSceneRef = *mut Scene;
pub type PFSceneProxyRef = *mut SceneProxy; pub type PFSceneProxyRef = *mut SceneProxy;
#[repr(C)] #[repr(C)]
pub struct PFRendererMode {
pub level: PFRendererLevel,
}
pub type PFDestFramebufferRef = *mut c_void;
#[repr(C)]
pub struct PFRendererOptions { pub struct PFRendererOptions {
pub dest: PFDestFramebufferRef,
pub background_color: PFColorF, pub background_color: PFColorF,
pub flags: PFRendererOptionsFlags, pub flags: PFRendererOptionsFlags,
} }
pub type PFRendererOptionsFlags = u8; pub type PFRendererOptionsFlags = u8;
pub type PFBuildOptionsRef = *mut BuildOptions; pub type PFBuildOptionsRef = *mut BuildOptions;
pub type PFRenderTransformRef = *mut RenderTransform; pub type PFRenderTransformRef = *mut RenderTransform;
pub type PFRendererLevel = u8;
// `canvas` // `canvas`
@ -541,12 +554,12 @@ pub unsafe extern "C" fn PFGLDestFramebufferDestroy(dest_framebuffer: PFGLDestFr
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFGLRendererCreate(device: PFGLDeviceRef, pub unsafe extern "C" fn PFGLRendererCreate(device: PFGLDeviceRef,
resources: PFResourceLoaderRef, resources: PFResourceLoaderRef,
dest_framebuffer: PFGLDestFramebufferRef, mode: *const PFRendererMode,
options: *const PFRendererOptions) options: *const PFRendererOptions)
-> PFGLRendererRef { -> PFGLRendererRef {
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device), Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
&*((*resources).0), &*((*resources).0),
*Box::from_raw(dest_framebuffer), (*mode).to_rust(),
(*options).to_rust()))) (*options).to_rust())))
} }
@ -557,7 +570,7 @@ pub unsafe extern "C" fn PFGLRendererDestroy(renderer: PFGLRendererRef) {
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFGLRendererGetDevice(renderer: PFGLRendererRef) -> PFGLDeviceRef { pub unsafe extern "C" fn PFGLRendererGetDevice(renderer: PFGLRendererRef) -> PFGLDeviceRef {
&mut (*renderer).device (*renderer).device_mut()
} }
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))] #[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
@ -581,12 +594,12 @@ pub unsafe extern "C" fn PFMetalDestFramebufferDestroy(dest_framebuffer:
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFMetalRendererCreate(device: PFMetalDeviceRef, pub unsafe extern "C" fn PFMetalRendererCreate(device: PFMetalDeviceRef,
resources: PFResourceLoaderRef, resources: PFResourceLoaderRef,
dest_framebuffer: PFMetalDestFramebufferRef, mode: *const PFRendererMode,
options: *const PFRendererOptions) options: *const PFRendererOptions)
-> PFMetalRendererRef { -> PFMetalRendererRef {
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device), Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
&*((*resources).0), &*((*resources).0),
*Box::from_raw(dest_framebuffer), (*mode).to_rust(),
(*options).to_rust()))) (*options).to_rust())))
} }
@ -603,7 +616,7 @@ pub unsafe extern "C" fn PFMetalRendererDestroy(renderer: PFMetalRendererRef) {
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFMetalRendererGetDevice(renderer: PFMetalRendererRef) pub unsafe extern "C" fn PFMetalRendererGetDevice(renderer: PFMetalRendererRef)
-> PFMetalDeviceRef { -> PFMetalDeviceRef {
&mut (*renderer).device (*renderer).device_mut()
} }
/// This function does not take ownership of `renderer` or `build_options`. Therefore, if you /// This function does not take ownership of `renderer` or `build_options`. Therefore, if you
@ -631,7 +644,8 @@ pub unsafe extern "C" fn PFSceneProxyBuildAndRenderMetal(scene_proxy: PFScenePro
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFMetalDeviceCreate(layer: *mut CAMetalLayer) pub unsafe extern "C" fn PFMetalDeviceCreate(layer: *mut CAMetalLayer)
-> PFMetalDeviceRef { -> PFMetalDeviceRef {
let device = Device::system_default().expect("Failed to get Metal system default device!"); let device =
metal::Device::system_default().expect("Failed to get Metal system default device!");
let layer = CoreAnimationLayerRef::from_ptr(layer); let layer = CoreAnimationLayerRef::from_ptr(layer);
Box::into_raw(Box::new(MetalDevice::new(device, layer.next_drawable().unwrap()))) Box::into_raw(Box::new(MetalDevice::new(device, layer.next_drawable().unwrap())))
} }
@ -696,9 +710,12 @@ pub unsafe extern "C" fn PFSceneDestroy(scene: PFSceneRef) {
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFSceneProxyCreateFromSceneAndRayonExecutor(scene: PFSceneRef) pub unsafe extern "C" fn PFSceneProxyCreateFromSceneAndRayonExecutor(scene: PFSceneRef,
level: PFRendererLevel)
-> PFSceneProxyRef { -> PFSceneProxyRef {
Box::into_raw(Box::new(SceneProxy::from_scene(*Box::from_raw(scene), RayonExecutor))) Box::into_raw(Box::new(SceneProxy::from_scene(*Box::from_raw(scene),
to_rust_renderer_level(level),
RayonExecutor)))
} }
#[no_mangle] #[no_mangle]
@ -807,17 +824,35 @@ impl PFPerspective {
// Helpers for `renderer` // Helpers for `renderer`
impl PFRendererOptions { impl PFRendererMode {
pub fn to_rust(&self) -> RendererOptions { pub fn to_rust(&self) -> RendererMode {
let has_background_color = self.flags & PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR; RendererMode {
RendererOptions { level: to_rust_renderer_level(self.level),
background_color: if has_background_color != 0 {
Some(self.background_color.to_rust())
} else {
None
},
// TODO(pcwalton): Expose this in the C API.
no_compute: false,
} }
} }
} }
impl PFRendererOptions {
pub fn to_rust<D>(&self) -> RendererOptions<D> where D: Device {
let has_background_color = self.flags & PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR;
let show_debug_ui = (self.flags & PF_RENDERER_OPTIONS_FLAGS_SHOW_DEBUG_UI) != 0;
unsafe {
RendererOptions {
background_color: if has_background_color != 0 {
Some(self.background_color.to_rust())
} else {
None
},
dest: *Box::from_raw(self.dest as *mut DestFramebuffer<D>),
show_debug_ui,
}
}
}
}
fn to_rust_renderer_level(level: PFRendererLevel) -> RendererLevel {
match level {
PF_RENDERER_LEVEL_D3D9 => RendererLevel::D3D9,
_ => RendererLevel::D3D11,
}
}