From 23c171fb6fe10176e3c603c824d248a8c33e643f Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 23 Jun 2020 12:50:04 -0700 Subject: [PATCH] Refactor GPU a bit more --- renderer/src/gpu/blend.rs | 264 ++++++++++++++++++++++++++++++++++++++ renderer/src/gpu/mod.rs | 4 + renderer/src/lib.rs | 3 +- 3 files changed, 269 insertions(+), 2 deletions(-) create mode 100644 renderer/src/gpu/blend.rs diff --git a/renderer/src/gpu/blend.rs b/renderer/src/gpu/blend.rs new file mode 100644 index 00000000..02ae3924 --- /dev/null +++ b/renderer/src/gpu/blend.rs @@ -0,0 +1,264 @@ +// pathfinder/renderer/src/gpu/blend.rs +// +// Copyright © 2020 The Pathfinder Project Developers. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Helpers for blending. + +use crate::gpu_data::ColorCombineMode; +use crate::paint::PaintCompositeOp; +use pathfinder_content::effects::BlendMode; +use pathfinder_gpu::{BlendFactor, BlendState}; + +const COMBINER_CTRL_COLOR_COMBINE_SRC_IN: i32 = 0x1; +const COMBINER_CTRL_COLOR_COMBINE_DEST_IN: i32 = 0x2; + +const COMBINER_CTRL_COMPOSITE_NORMAL: i32 = 0x0; +const COMBINER_CTRL_COMPOSITE_MULTIPLY: i32 = 0x1; +const COMBINER_CTRL_COMPOSITE_SCREEN: i32 = 0x2; +const COMBINER_CTRL_COMPOSITE_OVERLAY: i32 = 0x3; +const COMBINER_CTRL_COMPOSITE_DARKEN: i32 = 0x4; +const COMBINER_CTRL_COMPOSITE_LIGHTEN: i32 = 0x5; +const COMBINER_CTRL_COMPOSITE_COLOR_DODGE: i32 = 0x6; +const COMBINER_CTRL_COMPOSITE_COLOR_BURN: i32 = 0x7; +const COMBINER_CTRL_COMPOSITE_HARD_LIGHT: i32 = 0x8; +const COMBINER_CTRL_COMPOSITE_SOFT_LIGHT: i32 = 0x9; +const COMBINER_CTRL_COMPOSITE_DIFFERENCE: i32 = 0xa; +const COMBINER_CTRL_COMPOSITE_EXCLUSION: i32 = 0xb; +const COMBINER_CTRL_COMPOSITE_HUE: i32 = 0xc; +const COMBINER_CTRL_COMPOSITE_SATURATION: i32 = 0xd; +const COMBINER_CTRL_COMPOSITE_COLOR: i32 = 0xe; +const COMBINER_CTRL_COMPOSITE_LUMINOSITY: i32 = 0xf; + +pub(crate) trait ToBlendState { + fn to_blend_state(self) -> Option; +} + +impl ToBlendState for BlendMode { + fn to_blend_state(self) -> Option { + match self { + BlendMode::Clear => { + Some(BlendState { + src_rgb_factor: BlendFactor::Zero, + dest_rgb_factor: BlendFactor::Zero, + src_alpha_factor: BlendFactor::Zero, + dest_alpha_factor: BlendFactor::Zero, + ..BlendState::default() + }) + } + BlendMode::SrcOver => { + Some(BlendState { + src_rgb_factor: BlendFactor::One, + dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, + src_alpha_factor: BlendFactor::One, + dest_alpha_factor: BlendFactor::OneMinusSrcAlpha, + ..BlendState::default() + }) + } + BlendMode::DestOver => { + Some(BlendState { + src_rgb_factor: BlendFactor::OneMinusDestAlpha, + dest_rgb_factor: BlendFactor::One, + src_alpha_factor: BlendFactor::OneMinusDestAlpha, + dest_alpha_factor: BlendFactor::One, + ..BlendState::default() + }) + } + BlendMode::SrcIn => { + Some(BlendState { + src_rgb_factor: BlendFactor::DestAlpha, + dest_rgb_factor: BlendFactor::Zero, + src_alpha_factor: BlendFactor::DestAlpha, + dest_alpha_factor: BlendFactor::Zero, + ..BlendState::default() + }) + } + BlendMode::DestIn => { + Some(BlendState { + src_rgb_factor: BlendFactor::Zero, + dest_rgb_factor: BlendFactor::SrcAlpha, + src_alpha_factor: BlendFactor::Zero, + dest_alpha_factor: BlendFactor::SrcAlpha, + ..BlendState::default() + }) + } + BlendMode::SrcOut => { + Some(BlendState { + src_rgb_factor: BlendFactor::OneMinusDestAlpha, + dest_rgb_factor: BlendFactor::Zero, + src_alpha_factor: BlendFactor::OneMinusDestAlpha, + dest_alpha_factor: BlendFactor::Zero, + ..BlendState::default() + }) + } + BlendMode::DestOut => { + Some(BlendState { + src_rgb_factor: BlendFactor::Zero, + dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, + src_alpha_factor: BlendFactor::Zero, + dest_alpha_factor: BlendFactor::OneMinusSrcAlpha, + ..BlendState::default() + }) + } + BlendMode::SrcAtop => { + Some(BlendState { + src_rgb_factor: BlendFactor::DestAlpha, + dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, + src_alpha_factor: BlendFactor::DestAlpha, + dest_alpha_factor: BlendFactor::OneMinusSrcAlpha, + ..BlendState::default() + }) + } + BlendMode::DestAtop => { + Some(BlendState { + src_rgb_factor: BlendFactor::OneMinusDestAlpha, + dest_rgb_factor: BlendFactor::SrcAlpha, + src_alpha_factor: BlendFactor::OneMinusDestAlpha, + dest_alpha_factor: BlendFactor::SrcAlpha, + ..BlendState::default() + }) + } + BlendMode::Xor => { + Some(BlendState { + src_rgb_factor: BlendFactor::OneMinusDestAlpha, + dest_rgb_factor: BlendFactor::OneMinusSrcAlpha, + src_alpha_factor: BlendFactor::OneMinusDestAlpha, + dest_alpha_factor: BlendFactor::OneMinusSrcAlpha, + ..BlendState::default() + }) + } + BlendMode::Lighter => { + Some(BlendState { + src_rgb_factor: BlendFactor::One, + dest_rgb_factor: BlendFactor::One, + src_alpha_factor: BlendFactor::One, + dest_alpha_factor: BlendFactor::One, + ..BlendState::default() + }) + } + BlendMode::Copy | + BlendMode::Darken | + BlendMode::Lighten | + BlendMode::Multiply | + BlendMode::Screen | + BlendMode::HardLight | + BlendMode::Overlay | + BlendMode::ColorDodge | + BlendMode::ColorBurn | + BlendMode::SoftLight | + BlendMode::Difference | + BlendMode::Exclusion | + BlendMode::Hue | + BlendMode::Saturation | + BlendMode::Color | + BlendMode::Luminosity => { + // Blending is done manually in the shader. + None + } + } + } +} + +pub(crate) trait ToCompositeCtrl { + fn to_composite_ctrl(&self) -> i32; +} + +impl ToCompositeCtrl for BlendMode { + fn to_composite_ctrl(&self) -> i32 { + match *self { + BlendMode::SrcOver | + BlendMode::SrcAtop | + BlendMode::DestOver | + BlendMode::DestOut | + BlendMode::Xor | + BlendMode::Lighter | + BlendMode::Clear | + BlendMode::Copy | + BlendMode::SrcIn | + BlendMode::SrcOut | + BlendMode::DestIn | + BlendMode::DestAtop => COMBINER_CTRL_COMPOSITE_NORMAL, + BlendMode::Multiply => COMBINER_CTRL_COMPOSITE_MULTIPLY, + BlendMode::Darken => COMBINER_CTRL_COMPOSITE_DARKEN, + BlendMode::Lighten => COMBINER_CTRL_COMPOSITE_LIGHTEN, + BlendMode::Screen => COMBINER_CTRL_COMPOSITE_SCREEN, + BlendMode::Overlay => COMBINER_CTRL_COMPOSITE_OVERLAY, + BlendMode::ColorDodge => COMBINER_CTRL_COMPOSITE_COLOR_DODGE, + BlendMode::ColorBurn => COMBINER_CTRL_COMPOSITE_COLOR_BURN, + BlendMode::HardLight => COMBINER_CTRL_COMPOSITE_HARD_LIGHT, + BlendMode::SoftLight => COMBINER_CTRL_COMPOSITE_SOFT_LIGHT, + BlendMode::Difference => COMBINER_CTRL_COMPOSITE_DIFFERENCE, + BlendMode::Exclusion => COMBINER_CTRL_COMPOSITE_EXCLUSION, + BlendMode::Hue => COMBINER_CTRL_COMPOSITE_HUE, + BlendMode::Saturation => COMBINER_CTRL_COMPOSITE_SATURATION, + BlendMode::Color => COMBINER_CTRL_COMPOSITE_COLOR, + BlendMode::Luminosity => COMBINER_CTRL_COMPOSITE_LUMINOSITY, + } + } +} + +impl ToCompositeCtrl for ColorCombineMode { + fn to_composite_ctrl(&self) -> i32 { + match *self { + ColorCombineMode::None => 0, + ColorCombineMode::SrcIn => COMBINER_CTRL_COLOR_COMBINE_SRC_IN, + ColorCombineMode::DestIn => COMBINER_CTRL_COLOR_COMBINE_DEST_IN, + } + } +} + +pub trait BlendModeExt { + fn needs_readable_framebuffer(self) -> bool; +} + +impl BlendModeExt for BlendMode { + fn needs_readable_framebuffer(self) -> bool { + match self { + BlendMode::Clear | + BlendMode::SrcOver | + BlendMode::DestOver | + BlendMode::SrcIn | + BlendMode::DestIn | + BlendMode::SrcOut | + BlendMode::DestOut | + BlendMode::SrcAtop | + BlendMode::DestAtop | + BlendMode::Xor | + BlendMode::Lighter | + BlendMode::Copy => false, + BlendMode::Lighten | + BlendMode::Darken | + BlendMode::Multiply | + BlendMode::Screen | + BlendMode::HardLight | + BlendMode::Overlay | + BlendMode::ColorDodge | + BlendMode::ColorBurn | + BlendMode::SoftLight | + BlendMode::Difference | + BlendMode::Exclusion | + BlendMode::Hue | + BlendMode::Saturation | + BlendMode::Color | + BlendMode::Luminosity => true, + } + } +} + +pub(crate) trait ToCombineMode { + fn to_combine_mode(self) -> i32; +} + +impl ToCombineMode for PaintCompositeOp { + fn to_combine_mode(self) -> i32 { + match self { + PaintCompositeOp::DestIn => COMBINER_CTRL_COLOR_COMBINE_DEST_IN, + PaintCompositeOp::SrcIn => COMBINER_CTRL_COLOR_COMBINE_SRC_IN, + } + } +} diff --git a/renderer/src/gpu/mod.rs b/renderer/src/gpu/mod.rs index 9d005dec..322bb99b 100644 --- a/renderer/src/gpu/mod.rs +++ b/renderer/src/gpu/mod.rs @@ -10,8 +10,12 @@ //! The GPU renderer for Pathfinder 3. +pub mod d3d9; +pub mod d3d11; pub mod debug; pub mod options; +pub mod perf; pub mod renderer; +pub(crate) mod blend; pub(crate) mod shaders; diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 083f9ba3..ac43b530 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -1,6 +1,6 @@ // pathfinder/renderer/src/lib.rs // -// Copyright © 2019 The Pathfinder Project Developers. +// Copyright © 2020 The Pathfinder Project Developers. // // Licensed under the Apache License, Version 2.0 or the MIT license @@ -27,4 +27,3 @@ mod builder; mod tile_map; mod tiler; mod tiles; -mod z_buffer;