Rework renderer options

This commit is contained in:
Patrick Walton 2020-06-23 13:05:43 -07:00
parent 7a996d330c
commit 17356311d6
2 changed files with 88 additions and 13 deletions

View File

@ -11,13 +11,58 @@
use pathfinder_color::ColorF; use pathfinder_color::ColorF;
use pathfinder_geometry::rect::RectI; use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::vector::Vector2I; use pathfinder_geometry::vector::Vector2I;
use pathfinder_gpu::Device; use pathfinder_gpu::{Device, FeatureLevel};
/// Options that influence rendering. /// Renderer options that can't be changed after the renderer is created.
#[derive(Default)] pub struct RendererMode {
pub struct RendererOptions { /// 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<D> where D: Device {
/// Where the rendering should go: either to the default framebuffer (i.e. screen) or to a
/// custom framebuffer.
pub dest: DestFramebuffer<D>,
/// The background color. If not present, transparent is assumed.
pub background_color: Option<ColorF>, pub background_color: Option<ColorF>,
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<D>(device: &D) -> RendererMode where D: Device {
RendererMode { level: RendererLevel::default_for_device(device) }
}
}
impl<D> Default for RendererOptions<D> where D: Device {
#[inline]
fn default() -> RendererOptions<D> {
RendererOptions {
dest: DestFramebuffer::default(),
background_color: None,
show_debug_ui: false,
}
}
}
impl RendererLevel {
pub fn default_for_device<D>(device: &D) -> RendererLevel where D: Device {
match device.feature_level() {
FeatureLevel::D3D10 => RendererLevel::D3D9,
FeatureLevel::D3D11 => RendererLevel::D3D11,
}
}
} }
#[derive(Clone)] #[derive(Clone)]

View File

@ -10,6 +10,7 @@
//! Options that control how rendering is to be performed. //! Options that control how rendering is to be performed.
use crate::gpu::options::RendererLevel;
use crate::gpu_data::RenderCommand; use crate::gpu_data::RenderCommand;
use pathfinder_geometry::rect::RectF; use pathfinder_geometry::rect::RectF;
use pathfinder_geometry::transform2d::Transform2F; use pathfinder_geometry::transform2d::Transform2F;
@ -17,17 +18,21 @@ use pathfinder_geometry::transform3d::Perspective;
use pathfinder_geometry::vector::{Vector2F, Vector4F}; use pathfinder_geometry::vector::{Vector2F, Vector4F};
use pathfinder_content::clip::PolygonClipper3D; use pathfinder_content::clip::PolygonClipper3D;
pub trait RenderCommandListener: Send + Sync { pub struct RenderCommandListener<'a> {
fn send(&self, command: RenderCommand); send_fn: RenderCommandSendFunction<'a>,
} }
impl<F> RenderCommandListener for F pub type RenderCommandSendFunction<'a> = Box<dyn Fn(RenderCommand) + Send + Sync + 'a>;
where
F: Fn(RenderCommand) + Send + Sync, impl<'a> RenderCommandListener<'a> {
{
#[inline] #[inline]
fn send(&self, command: RenderCommand) { pub fn new(send_fn: RenderCommandSendFunction<'a>) -> RenderCommandListener<'a> {
(*self)(command) 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, pub(crate) subpixel_aa_enabled: bool,
} }
#[derive(Clone, Copy)]
pub(crate) enum PrepareMode {
CPU,
TransformCPUBinGPU,
GPU { transform: Transform2F },
}
impl PreparedBuildOptions { impl PreparedBuildOptions {
#[inline] #[inline]
pub(crate) fn bounding_quad(&self) -> BoundingQuad { pub(crate) fn bounding_quad(&self) -> BoundingQuad {
@ -128,6 +140,24 @@ impl PreparedBuildOptions {
_ => [Vector4F::default(); 4], _ => [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]; pub(crate) type BoundingQuad = [Vector4F; 4];