Allow rendering to non-default framebuffers

This commit is contained in:
Patrick Walton 2019-04-18 18:55:18 -07:00
parent 62a3fefca4
commit 58d55c5eaa
2 changed files with 72 additions and 24 deletions

View File

@ -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<W> DemoApp<W> 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<W> DemoApp<W> 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<W> DemoApp<W> 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<W> DemoApp<W> 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();
}

View File

@ -49,6 +49,7 @@ pub struct Renderer<D> where D: Device {
pub device: D,
// Core data
dest_framebuffer: DestFramebuffer<D>,
fill_program: FillProgram<D>,
solid_multicolor_tile_program: SolidTileMulticolorProgram<D>,
alpha_multicolor_tile_program: AlphaTileMulticolorProgram<D>,
@ -86,16 +87,12 @@ pub struct Renderer<D> where D: Device {
pub debug_ui: DebugUI<D>,
// Extra info
viewport: RectI32,
render_mode: RenderMode,
use_depth: bool,
}
impl<D> Renderer<D> 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<D>)
-> Renderer<D> {
let fill_program = FillProgram::new(&device, resources);
@ -150,10 +147,12 @@ impl<D> Renderer<D> 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<D> Renderer<D> where D: Device {
mask_framebuffer_cleared: false,
buffered_fills: vec![],
viewport,
render_mode: RenderMode::default(),
use_depth: false,
}
@ -242,7 +240,7 @@ impl<D> Renderer<D> 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<D> Renderer<D> 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<D>) {
self.dest_framebuffer = new_dest_framebuffer;
}
#[inline]
@ -506,12 +504,12 @@ impl<D> Renderer<D> 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<D> Renderer<D> 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<D> Renderer<D> 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<D> StencilVertexArray<D> where D: Device {
}
}
#[derive(Clone)]
pub enum DestFramebuffer<D> where D: Device {
Default { viewport: RectI32, window_size: Point2DI32 },
Other(D::Framebuffer),
}
impl<D> DestFramebuffer<D> 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,