use crate::backend::{BackendError, Renderer as _, WgpuRenderer as _};
use crate::color::Color;
use crate::scene::SceneBuilder;
#[cfg(feature = "vello-hybrid")]
use crate::backend::hybrid::HybridRenderer;
#[cfg(feature = "vello")]
use crate::backend::vello::VelloRenderer;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Backend {
#[cfg(feature = "vello")]
Vello,
#[cfg(feature = "vello-hybrid")]
Hybrid,
}
impl Default for Backend {
fn default() -> Self {
#[cfg(feature = "vello")]
{
Self::Vello
}
#[cfg(all(not(feature = "vello"), feature = "vello-hybrid"))]
{
Self::Hybrid
}
}
}
impl Backend {
pub(crate) fn target_usage(self) -> wgpu::TextureUsages {
match self {
#[cfg(feature = "vello")]
Self::Vello => VelloRenderer::REQUIRED_TARGET_USAGE,
#[cfg(feature = "vello-hybrid")]
Self::Hybrid => HybridRenderer::REQUIRED_TARGET_USAGE,
}
}
}
impl Backend {
pub(crate) fn can_present_directly(self) -> bool {
self.target_usage() == wgpu::TextureUsages::RENDER_ATTACHMENT
}
}
pub(crate) enum HostRenderer {
#[cfg(feature = "vello")]
Vello(Box<VelloRenderer>),
#[cfg(feature = "vello-hybrid")]
Hybrid(Box<HybridRenderer>),
}
impl HostRenderer {
pub(crate) fn new(
backend: Backend,
device: &wgpu::Device,
queue: &wgpu::Queue,
picking: bool,
) -> Result<Self, BackendError> {
match backend {
#[cfg(feature = "vello")]
Backend::Vello => Ok(Self::Vello(Box::new(if picking {
VelloRenderer::with_device_and_picking(device, queue)?
} else {
VelloRenderer::with_device(device, queue)?
}))),
#[cfg(feature = "vello-hybrid")]
Backend::Hybrid => Ok(Self::Hybrid(Box::new(if picking {
HybridRenderer::with_device_and_picking(device, queue)?
} else {
HybridRenderer::with_device(device, queue)?
}))),
}
}
pub(crate) fn set_target_format(&mut self, format: wgpu::TextureFormat) {
match self {
#[cfg(feature = "vello")]
Self::Vello(_) => {
let _ = format;
}
#[cfg(feature = "vello-hybrid")]
Self::Hybrid(r) => r.set_target_format(format),
}
}
pub(crate) fn set_refresh_pick(&mut self, refresh: bool) {
match self {
#[cfg(feature = "vello")]
Self::Vello(r) => r.set_refresh_pick(refresh),
#[cfg(feature = "vello-hybrid")]
Self::Hybrid(r) => r.set_refresh_pick(refresh),
}
}
pub(crate) fn scene(&mut self) -> &mut dyn SceneBuilder {
match self {
#[cfg(feature = "vello")]
Self::Vello(r) => r.scene(),
#[cfg(feature = "vello-hybrid")]
Self::Hybrid(r) => r.scene(),
}
}
pub(crate) fn render_to_texture(
&mut self,
view: &wgpu::TextureView,
width: u32,
height: u32,
background: Color,
) -> Result<(), BackendError> {
match self {
#[cfg(feature = "vello")]
Self::Vello(r) => r.render_to_texture(view, width, height, background),
#[cfg(feature = "vello-hybrid")]
Self::Hybrid(r) => r.render_to_texture(view, width, height, background),
}
}
#[cfg(all(feature = "canvas", target_arch = "wasm32"))]
pub(crate) fn render_to_texture_deferring_pick(
&mut self,
view: &wgpu::TextureView,
width: u32,
height: u32,
background: Color,
) -> Result<(), BackendError> {
match self {
#[cfg(feature = "vello")]
Self::Vello(r) => r.render_to_texture_deferring_pick(view, width, height, background),
#[cfg(feature = "vello-hybrid")]
Self::Hybrid(r) => r.render_to_texture_deferring_pick(view, width, height, background),
}
}
#[cfg(all(feature = "canvas", target_arch = "wasm32"))]
pub(crate) fn try_finish_pick(&mut self) -> Result<bool, BackendError> {
match self {
#[cfg(feature = "vello")]
Self::Vello(r) => r.try_finish_pick(),
#[cfg(feature = "vello-hybrid")]
Self::Hybrid(r) => r.try_finish_pick(),
}
}
}
impl crate::window::PickSource for HostRenderer {
fn pick_at(&self, x: u32, y: u32) -> Option<u32> {
match self {
#[cfg(feature = "vello")]
Self::Vello(r) => r.pick_at(x, y),
#[cfg(feature = "vello-hybrid")]
Self::Hybrid(r) => r.pick_at(x, y),
}
}
}