Skip to content

Commit

Permalink
Transition the existing postprocessing system to a layers system.
Browse files Browse the repository at this point in the history
This is preparatory work for composite ops and blurs.

Closes #261.
  • Loading branch information
pcwalton committed Feb 20, 2020
1 parent 25f9346 commit d9e994e
Show file tree
Hide file tree
Showing 14 changed files with 519 additions and 356 deletions.
5 changes: 5 additions & 0 deletions color/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ impl ColorF {
ColorF::default()
}

#[inline]
pub fn black() -> ColorF {
ColorF(F32x4::new(0.0, 0.0, 0.0, 1.0))
}

#[inline]
pub fn white() -> ColorF {
ColorF(F32x4::splat(1.0))
Expand Down
112 changes: 67 additions & 45 deletions demo/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ use crate::device::{GroundProgram, GroundVertexArray};
use crate::ui::{DemoUIModel, DemoUIPresenter, ScreenshotInfo, ScreenshotType, UIAction};
use crate::window::{Event, Keycode, SVGPath, Window, WindowSize};
use clap::{App, Arg};
use pathfinder_color::ColorU;
use pathfinder_export::{Export, FileFormat};
use pathfinder_geometry::rect::RectF;
use pathfinder_geometry::transform2d::Transform2F;
Expand All @@ -32,9 +31,9 @@ use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::Device;
use pathfinder_renderer::concurrent::scene_proxy::{RenderCommandStream, SceneProxy};
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::gpu::renderer::{RenderStats, RenderTime, Renderer};
use pathfinder_renderer::gpu::renderer::{PostprocessOptions, RenderStats, RenderTime, Renderer};
use pathfinder_renderer::options::{BuildOptions, RenderTransform};
use pathfinder_renderer::post::STEM_DARKENING_FACTORS;
use pathfinder_renderer::post::{DEFRINGING_KERNEL_CORE_GRAPHICS, STEM_DARKENING_FACTORS};
use pathfinder_renderer::scene::Scene;
use pathfinder_svg::BuiltSVG;
use pathfinder_ui::{MousePosition, UIEvent};
Expand Down Expand Up @@ -63,25 +62,6 @@ const CAMERA_ZOOM_AMOUNT_2D: f32 = 0.1;
// Half of the eye separation distance.
const DEFAULT_EYE_OFFSET: f32 = 0.025;

const LIGHT_BG_COLOR: ColorU = ColorU {
r: 248,
g: 248,
b: 248,
a: 255,
};
const DARK_BG_COLOR: ColorU = ColorU {
r: 32,
g: 32,
b: 32,
a: 255,
};
const TRANSPARENT_BG_COLOR: ColorU = ColorU {
r: 0,
g: 0,
b: 0,
a: 0,
};

const APPROX_FONT_SIZE: f32 = 16.0;

const MESSAGE_TIMEOUT_SECS: u64 = 5;
Expand All @@ -101,6 +81,7 @@ pub struct DemoApp<W> where W: Window {

window_size: WindowSize,

svg_tree: Tree,
scene_metadata: SceneMetadata,
render_transform: Option<RenderTransform>,
render_command_stream: Option<RenderCommandStream>,
Expand Down Expand Up @@ -151,20 +132,22 @@ impl<W> DemoApp<W> where W: Window {
// Set up the executor.
let executor = DemoExecutor::new(options.jobs);

let mut built_svg = load_scene(resources, &options.input_path);
let mut ui_model = DemoUIModel::new(&options);
let render_options = RendererOptions { background_color: None };

let effects = build_effects(&ui_model);

let (mut built_svg, svg_tree) = load_scene(resources, &options.input_path, effects);
let message = get_svg_building_message(&built_svg);

let viewport = window.viewport(options.mode.view(0));
let dest_framebuffer = DestFramebuffer::Default {
viewport,
window_size: window_size.device_size(),
};
// FIXME(pcwalton)
let render_options = RendererOptions {
background_color: None,
};

let renderer = Renderer::new(device, resources, dest_framebuffer, render_options);

let scene_metadata = SceneMetadata::new_clipping_view_box(&mut built_svg.scene,
viewport.size());
let camera = Camera::new(options.mode, scene_metadata.view_box, viewport.size());
Expand All @@ -177,8 +160,6 @@ impl<W> DemoApp<W> where W: Window {
&renderer.quad_vertex_positions_buffer(),
&renderer.quad_vertex_indices_buffer());

let mut ui_model = DemoUIModel::new(&options);

let mut message_epoch = 0;
emit_message::<W>(
&mut ui_model,
Expand All @@ -196,6 +177,7 @@ impl<W> DemoApp<W> where W: Window {

window_size,

svg_tree,
scene_metadata,
render_transform: None,
render_command_stream: None,
Expand Down Expand Up @@ -445,7 +427,11 @@ impl<W> DemoApp<W> where W: Window {
}

Event::OpenSVG(ref svg_path) => {
let mut built_svg = load_scene(self.window.resource_loader(), svg_path);
let effects = build_effects(&self.ui_model);
let (mut built_svg, svg_tree) = load_scene(self.window.resource_loader(),
svg_path,
effects);

self.ui_model.message = get_svg_building_message(&built_svg);

let viewport_size = self.window.viewport(self.ui_model.mode.view(0)).size();
Expand All @@ -456,6 +442,7 @@ impl<W> DemoApp<W> where W: Window {
viewport_size);

self.scene_proxy.replace_scene(built_svg.scene);
self.svg_tree = svg_tree;

self.dirty = true;
}
Expand Down Expand Up @@ -499,8 +486,6 @@ impl<W> DemoApp<W> where W: Window {
.to_f32()
.scale(self.window_size.backing_scale_factor);

self.ui_presenter.set_show_text_effects(self.scene_metadata.monochrome_color.is_some());

let mut ui_action = UIAction::None;
if self.options.ui == UIVisibility::All {
self.ui_presenter.update(
Expand Down Expand Up @@ -599,6 +584,15 @@ impl<W> DemoApp<W> where W: Window {
match ui_action {
UIAction::None => {}
UIAction::ModelChanged => self.dirty = true,
UIAction::EffectsChanged => {
let effects = build_effects(&self.ui_model);
let mut built_svg = build_svg_tree(&self.svg_tree, effects);
let viewport_size = self.window.viewport(self.ui_model.mode.view(0)).size();
self.scene_metadata =
SceneMetadata::new_clipping_view_box(&mut built_svg.scene, viewport_size);
self.scene_proxy.replace_scene(built_svg.scene);
self.dirty = true;
}
UIAction::TakeScreenshot(ref info) => {
self.pending_screenshot_info = Some((*info).clone());
self.dirty = true;
Expand Down Expand Up @@ -636,14 +630,6 @@ impl<W> DemoApp<W> where W: Window {
}
}
}

fn background_color(&self) -> ColorU {
match self.ui_model.background_color {
BackgroundColor::Light => LIGHT_BG_COLOR,
BackgroundColor::Dark => DARK_BG_COLOR,
BackgroundColor::Transparent => TRANSPARENT_BG_COLOR,
}
}
}

#[derive(Clone)]
Expand Down Expand Up @@ -756,7 +742,10 @@ pub enum UIVisibility {
All,
}

fn load_scene(resource_loader: &dyn ResourceLoader, input_path: &SVGPath) -> BuiltSVG {
fn load_scene(resource_loader: &dyn ResourceLoader,
input_path: &SVGPath,
effects: Option<PostprocessOptions>)
-> (BuiltSVG, Tree) {
let mut data;
match *input_path {
SVGPath::Default => data = resource_loader.slurp(DEFAULT_SVG_VIRTUAL_PATH).unwrap(),
Expand All @@ -767,7 +756,24 @@ fn load_scene(resource_loader: &dyn ResourceLoader, input_path: &SVGPath) -> Bui
}
};

BuiltSVG::from_tree(Tree::from_data(&data, &UsvgOptions::default()).unwrap())
let tree = Tree::from_data(&data, &UsvgOptions::default()).expect("Failed to parse the SVG!");
let built_svg = build_svg_tree(&tree, effects);
(built_svg, tree)
}

fn build_svg_tree(tree: &Tree, effects: Option<PostprocessOptions>) -> BuiltSVG {
let mut scene = Scene::new();
if let Some(effects) = effects {
scene.push_layer(effects);
}

let mut built_svg = BuiltSVG::from_tree_and_scene(&tree, scene);

if effects.is_some() {
built_svg.scene.pop_layer();
}

built_svg
}

fn center_of_window(window_size: &WindowSize) -> Vector2F {
Expand Down Expand Up @@ -842,16 +848,32 @@ impl BackgroundColor {

struct SceneMetadata {
view_box: RectF,
monochrome_color: Option<ColorU>,
}

impl SceneMetadata {
// FIXME(pcwalton): The fact that this mutates the scene is really ugly!
// Can we simplify this?
fn new_clipping_view_box(scene: &mut Scene, viewport_size: Vector2I) -> SceneMetadata {
let view_box = scene.view_box();
let monochrome_color = scene.monochrome_color();
scene.set_view_box(RectF::new(Vector2F::default(), viewport_size.to_f32()));
SceneMetadata { view_box, monochrome_color }
SceneMetadata { view_box }
}
}

fn build_effects(ui_model: &DemoUIModel) -> Option<PostprocessOptions> {
if !ui_model.gamma_correction_effect_enabled && !ui_model.subpixel_aa_effect_enabled {
return None;
}

Some(PostprocessOptions {
fg_color: ui_model.foreground_color().to_f32(),
bg_color: ui_model.background_color().to_f32(),
gamma_correction: ui_model.gamma_correction_effect_enabled,
defringing_kernel: if ui_model.subpixel_aa_effect_enabled {
// TODO(pcwalton): Select FreeType defringing kernel as necessary.
Some(DEFRINGING_KERNEL_CORE_GRAPHICS)
} else {
None
},
})
}
23 changes: 2 additions & 21 deletions demo/common/src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::transform3d::Transform4F;
use pathfinder_geometry::vector::{Vector2I, Vector4F};
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
use pathfinder_renderer::gpu::renderer::PostprocessOptions;
use pathfinder_renderer::gpu_data::RenderCommand;
use pathfinder_renderer::options::RenderTransform;
use pathfinder_renderer::post::DEFRINGING_KERNEL_CORE_GRAPHICS;
use std::path::PathBuf;

const GROUND_SOLID_COLOR: ColorU = ColorU {
Expand Down Expand Up @@ -88,7 +86,7 @@ impl<W> DemoApp<W> where W: Window {

// Clear to the appropriate color.
let clear_color = match mode {
Mode::TwoD => Some(self.background_color().to_f32()),
Mode::TwoD => Some(self.ui_model.background_color().to_f32()),
Mode::ThreeD => None,
Mode::VR => Some(ColorF::transparent_black()),
};
Expand Down Expand Up @@ -221,7 +219,7 @@ impl<W> DemoApp<W> where W: Window {

// Don't clear the first scene after drawing it.
let clear_color = if render_scene_index == 0 {
Some(self.background_color().to_f32())
Some(self.ui_model.background_color().to_f32())
} else {
None
};
Expand Down Expand Up @@ -251,23 +249,6 @@ impl<W> DemoApp<W> where W: Window {
}

fn render_vector_scene(&mut self) {
match self.scene_metadata.monochrome_color {
None => self.renderer.set_postprocess_options(None),
Some(fg_color) => {
self.renderer.set_postprocess_options(Some(PostprocessOptions {
fg_color: fg_color.to_f32(),
bg_color: self.background_color().to_f32(),
gamma_correction: self.ui_model.gamma_correction_effect_enabled,
defringing_kernel: if self.ui_model.subpixel_aa_effect_enabled {
// TODO(pcwalton): Select FreeType defringing kernel as necessary.
Some(DEFRINGING_KERNEL_CORE_GRAPHICS)
} else {
None
},
}))
}
}

if self.ui_model.mode == Mode::TwoD {
self.renderer.disable_depth();
} else {
Expand Down
Loading

0 comments on commit d9e994e

Please sign in to comment.