From 17356311d6fbefca224e66401e661d10c0c5a5a9 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 23 Jun 2020 13:05:43 -0700 Subject: [PATCH] Rework renderer options --- renderer/src/gpu/options.rs | 55 +++++++++++++++++++++++++++++++++---- renderer/src/options.rs | 46 +++++++++++++++++++++++++------ 2 files changed, 88 insertions(+), 13 deletions(-) diff --git a/renderer/src/gpu/options.rs b/renderer/src/gpu/options.rs index 435a6317..e5b6aa97 100644 --- a/renderer/src/gpu/options.rs +++ b/renderer/src/gpu/options.rs @@ -11,13 +11,58 @@ use pathfinder_color::ColorF; use pathfinder_geometry::rect::RectI; use pathfinder_geometry::vector::Vector2I; -use pathfinder_gpu::Device; +use pathfinder_gpu::{Device, FeatureLevel}; -/// Options that influence rendering. -#[derive(Default)] -pub struct RendererOptions { +/// Renderer options that can't be changed after the renderer is created. +pub struct RendererMode { + /// The level of hardware features that the renderer will attempt to use. + pub level: RendererLevel, +} + +/// Options that influence rendering that can be changed at runtime. +pub struct RendererOptions where D: Device { + /// Where the rendering should go: either to the default framebuffer (i.e. screen) or to a + /// custom framebuffer. + pub dest: DestFramebuffer, + /// The background color. If not present, transparent is assumed. pub background_color: Option, - pub no_compute: bool, + /// Whether to display the debug UI. + pub show_debug_ui: bool, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum RendererLevel { + /// Direct3D 9/OpenGL 3.0/WebGL 2.0 compatibility. Bin on CPU, fill and composite on GPU. + D3D9, + /// Direct3D 11/OpenGL 4.3/Metal/Vulkan/WebGPU compatibility. Bin, fill, and composite on GPU. + D3D11, +} + +impl RendererMode { + #[inline] + pub fn default_for_device(device: &D) -> RendererMode where D: Device { + RendererMode { level: RendererLevel::default_for_device(device) } + } +} + +impl Default for RendererOptions where D: Device { + #[inline] + fn default() -> RendererOptions { + RendererOptions { + dest: DestFramebuffer::default(), + background_color: None, + show_debug_ui: false, + } + } +} + +impl RendererLevel { + pub fn default_for_device(device: &D) -> RendererLevel where D: Device { + match device.feature_level() { + FeatureLevel::D3D10 => RendererLevel::D3D9, + FeatureLevel::D3D11 => RendererLevel::D3D11, + } + } } #[derive(Clone)] diff --git a/renderer/src/options.rs b/renderer/src/options.rs index 86ba541e..646bdda4 100644 --- a/renderer/src/options.rs +++ b/renderer/src/options.rs @@ -10,6 +10,7 @@ //! Options that control how rendering is to be performed. +use crate::gpu::options::RendererLevel; use crate::gpu_data::RenderCommand; use pathfinder_geometry::rect::RectF; use pathfinder_geometry::transform2d::Transform2F; @@ -17,17 +18,21 @@ use pathfinder_geometry::transform3d::Perspective; use pathfinder_geometry::vector::{Vector2F, Vector4F}; use pathfinder_content::clip::PolygonClipper3D; -pub trait RenderCommandListener: Send + Sync { - fn send(&self, command: RenderCommand); +pub struct RenderCommandListener<'a> { + send_fn: RenderCommandSendFunction<'a>, } -impl RenderCommandListener for F -where - F: Fn(RenderCommand) + Send + Sync, -{ +pub type RenderCommandSendFunction<'a> = Box; + +impl<'a> RenderCommandListener<'a> { #[inline] - fn send(&self, command: RenderCommand) { - (*self)(command) + pub fn new(send_fn: RenderCommandSendFunction<'a>) -> RenderCommandListener<'a> { + RenderCommandListener { send_fn } + } + + #[inline] + pub fn send(&self, render_command: RenderCommand) { + (self.send_fn)(render_command) } } @@ -120,6 +125,13 @@ pub(crate) struct PreparedBuildOptions { pub(crate) subpixel_aa_enabled: bool, } +#[derive(Clone, Copy)] +pub(crate) enum PrepareMode { + CPU, + TransformCPUBinGPU, + GPU { transform: Transform2F }, +} + impl PreparedBuildOptions { #[inline] pub(crate) fn bounding_quad(&self) -> BoundingQuad { @@ -128,6 +140,24 @@ impl PreparedBuildOptions { _ => [Vector4F::default(); 4], } } + + #[inline] + pub(crate) fn to_prepare_mode(&self, renderer_level: RendererLevel) -> PrepareMode { + match renderer_level { + RendererLevel::D3D9 => PrepareMode::CPU, + RendererLevel::D3D11 => { + match self.transform { + PreparedRenderTransform::Perspective { .. } => PrepareMode::TransformCPUBinGPU, + PreparedRenderTransform::None => { + PrepareMode::GPU { transform: Transform2F::default() } + } + PreparedRenderTransform::Transform2D(transform) => { + PrepareMode::GPU { transform } + } + } + } + } + } } pub(crate) type BoundingQuad = [Vector4F; 4];