diff --git a/demo/common/src/lib.rs b/demo/common/src/lib.rs index 8f2ce9a4..67cdbe9b 100644 --- a/demo/common/src/lib.rs +++ b/demo/common/src/lib.rs @@ -26,7 +26,7 @@ use pathfinder_gpu::resources::ResourceLoader; use pathfinder_gpu::{DepthFunc, DepthState, Device, Primitive, RenderState, StencilFunc}; use pathfinder_gpu::{StencilState, UniformData}; use pathfinder_renderer::builder::{RenderOptions, RenderTransform, SceneBuilder}; -use pathfinder_renderer::gpu::renderer::{RenderMode, RenderStats, Renderer}; +use pathfinder_renderer::gpu::renderer::{DestFramebuffer, RenderMode, RenderStats, Renderer}; use pathfinder_renderer::gpu_data::RenderCommand; use pathfinder_renderer::post::{DEFRINGING_KERNEL_CORE_GRAPHICS, STEM_DARKENING_FACTORS}; use pathfinder_renderer::scene::{Scene, SceneDescriptor}; @@ -130,10 +130,12 @@ impl DemoApp where W: Window { let monochrome_scene_color = built_svg.scene.monochrome_color(); let viewport = window.viewport(options.mode.view(0)); - let renderer = Renderer::new(device, - resources, - viewport, - window_size.device_size()); + let dest_framebuffer = DestFramebuffer::Default { + viewport, + window_size: window_size.device_size(), + }; + + let renderer = Renderer::new(device, resources, dest_framebuffer); let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone()); scene_thread_proxy.set_drawable_size(viewport.size()); @@ -207,7 +209,10 @@ impl DemoApp where W: Window { let view = self.ui.mode.view(render_scene_index); let viewport = self.window.viewport(view); self.window.make_current(view); - self.renderer.set_viewport(viewport); + self.renderer.set_dest_framebuffer(DestFramebuffer::Default { + viewport, + window_size: self.window_size.device_size(), + }); self.renderer.device.clear(Some(self.background_color().to_f32().0), Some(1.0), Some(0)); } @@ -391,7 +396,10 @@ impl DemoApp where W: Window { let view = self.ui.mode.view(render_scene_index); let viewport = self.window.viewport(view); self.window.make_current(view); - self.renderer.set_viewport(viewport); + self.renderer.set_dest_framebuffer(DestFramebuffer::Default { + viewport, + window_size: self.window_size.device_size(), + }); self.draw_environment(render_scene_index); self.render_vector_scene(); @@ -427,7 +435,10 @@ impl DemoApp where W: Window { if self.options.ui != UIVisibility::None { let viewport = self.window.viewport(View::Mono); self.window.make_current(View::Mono); - self.renderer.set_viewport(viewport); + self.renderer.set_dest_framebuffer(DestFramebuffer::Default { + viewport, + window_size: self.window_size.device_size(), + }); self.renderer.draw_debug_ui(); } diff --git a/renderer/src/gpu/renderer.rs b/renderer/src/gpu/renderer.rs index 2c128708..3467e359 100644 --- a/renderer/src/gpu/renderer.rs +++ b/renderer/src/gpu/renderer.rs @@ -49,6 +49,7 @@ pub struct Renderer where D: Device { pub device: D, // Core data + dest_framebuffer: DestFramebuffer, fill_program: FillProgram, solid_multicolor_tile_program: SolidTileMulticolorProgram, alpha_multicolor_tile_program: AlphaTileMulticolorProgram, @@ -86,16 +87,12 @@ pub struct Renderer where D: Device { pub debug_ui: DebugUI, // Extra info - viewport: RectI32, render_mode: RenderMode, use_depth: bool, } impl Renderer where D: Device { - pub fn new(device: D, - resources: &dyn ResourceLoader, - viewport: RectI32, - main_framebuffer_size: Point2DI32) + pub fn new(device: D, resources: &dyn ResourceLoader, dest_framebuffer: DestFramebuffer) -> Renderer { let fill_program = FillProgram::new(&device, resources); @@ -150,10 +147,12 @@ impl Renderer where D: Device { FILL_COLORS_TEXTURE_HEIGHT); let fill_colors_texture = device.create_texture(TextureFormat::RGBA8, fill_colors_size); - let debug_ui = DebugUI::new(&device, resources, main_framebuffer_size); + let debug_ui = DebugUI::new(&device, resources, dest_framebuffer.window_size(&device)); Renderer { device, + + dest_framebuffer, fill_program, solid_monochrome_tile_program, alpha_monochrome_tile_program, @@ -186,7 +185,6 @@ impl Renderer where D: Device { mask_framebuffer_cleared: false, buffered_fills: vec![], - viewport, render_mode: RenderMode::default(), use_depth: false, } @@ -242,7 +240,7 @@ impl Renderer where D: Device { } pub fn draw_debug_ui(&self) { - self.device.bind_default_framebuffer(self.viewport); + self.bind_main_framebuffer(); self.debug_ui.draw(&self.device); } @@ -258,8 +256,8 @@ impl Renderer where D: Device { } #[inline] - pub fn set_viewport(&mut self, new_viewport: RectI32) { - self.viewport = new_viewport; + pub fn set_dest_framebuffer(&mut self, new_dest_framebuffer: DestFramebuffer) { + self.dest_framebuffer = new_dest_framebuffer; } #[inline] @@ -506,12 +504,12 @@ impl Renderer where D: Device { } } - self.device.bind_default_framebuffer(self.viewport); + self.bind_main_framebuffer(); self.device.bind_vertex_array(&self.postprocess_vertex_array.vertex_array); self.device.use_program(&self.postprocess_program.program); self.device.set_uniform(&self.postprocess_program.framebuffer_size_uniform, - UniformData::Vec2(self.viewport.size().to_f32().0)); + UniformData::Vec2(self.main_viewport().size().to_f32().0)); match defringing_kernel { Some(ref kernel) => { self.device.set_uniform(&self.postprocess_program.kernel_uniform, @@ -602,7 +600,18 @@ impl Renderer where D: Device { if self.postprocessing_needed() { self.device.bind_framebuffer(self.postprocess_source_framebuffer.as_ref().unwrap()); } else { - self.device.bind_default_framebuffer(self.viewport); + self.bind_main_framebuffer(); + } + } + + fn bind_main_framebuffer(&self) { + match self.dest_framebuffer { + DestFramebuffer::Default { viewport, .. } => { + self.device.bind_default_framebuffer(viewport) + } + DestFramebuffer::Other(ref framebuffer) => { + self.device.bind_framebuffer(framebuffer) + } } } @@ -646,12 +655,23 @@ impl Renderer where D: Device { } fn draw_viewport(&self) -> RectI32 { + let main_viewport = self.main_viewport(); match self.render_mode { RenderMode::Monochrome { defringing_kernel: Some(..), .. } => { - RectI32::new(Point2DI32::default(), - self.viewport.size().scale_xy(Point2DI32::new(3, 1))) + let scale = Point2DI32::new(3, 1); + RectI32::new(Point2DI32::default(), main_viewport.size().scale_xy(scale)) + } + _ => main_viewport + } + } + + fn main_viewport(&self) -> RectI32 { + match self.dest_framebuffer { + DestFramebuffer::Default { viewport, .. } => viewport, + DestFramebuffer::Other(ref framebuffer) => { + let size = self.device.texture_size(self.device.framebuffer_texture(framebuffer)); + RectI32::new(Point2DI32::default(), size) } - _ => self.viewport } } } @@ -1079,6 +1099,23 @@ impl StencilVertexArray where D: Device { } } +#[derive(Clone)] +pub enum DestFramebuffer where D: Device { + Default { viewport: RectI32, window_size: Point2DI32 }, + Other(D::Framebuffer), +} + +impl DestFramebuffer where D: Device { + fn window_size(&self, device: &D) -> Point2DI32 { + match *self { + DestFramebuffer::Default { window_size, .. } => window_size, + DestFramebuffer::Other(ref framebuffer) => { + device.texture_size(device.framebuffer_texture(framebuffer)) + } + } + } +} + #[derive(Clone, Copy)] pub enum RenderMode { Multicolor,