Expose individual blend factors in `pathfinder_gpu`

This commit is contained in:
Patrick Walton 2020-02-20 15:28:37 -08:00
parent 16a2de88df
commit 0c3dad974f
5 changed files with 141 additions and 113 deletions

View File

@ -19,7 +19,7 @@ use half::f16;
use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::vector::Vector2I;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::{BlendFunc, BlendOp, BufferData, BufferTarget, BufferUploadMode, ClearOps};
use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode, ClearOps};
use pathfinder_gpu::{DepthFunc, Device, Primitive, RenderOptions, RenderState, RenderTarget};
use pathfinder_gpu::{ShaderKind, StencilFunc, TextureData, TextureDataRef, TextureFormat};
use pathfinder_gpu::{UniformData, VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
@ -92,40 +92,11 @@ impl GLDevice {
gl::Disable(gl::BLEND); ck();
}
Some(ref blend) => {
match blend.func {
BlendFunc::RGBOneAlphaOne => {
gl::BlendFunc(gl::ONE, gl::ONE); ck();
}
BlendFunc::RGBOneAlphaOneMinusSrcAlpha => {
gl::BlendFuncSeparate(gl::ONE,
gl::ONE_MINUS_SRC_ALPHA,
gl::ONE,
gl::ONE); ck();
}
BlendFunc::RGBSrcAlphaAlphaOneMinusSrcAlpha => {
gl::BlendFuncSeparate(gl::SRC_ALPHA,
gl::ONE_MINUS_SRC_ALPHA,
gl::ONE,
gl::ONE); ck();
}
}
match blend.op {
BlendOp::Add => {
gl::BlendEquation(gl::FUNC_ADD); ck();
}
BlendOp::Subtract => {
gl::BlendEquation(gl::FUNC_SUBTRACT); ck();
}
BlendOp::ReverseSubtract => {
gl::BlendEquation(gl::FUNC_REVERSE_SUBTRACT); ck();
}
BlendOp::Min => {
gl::BlendEquation(gl::MIN); ck();
}
BlendOp::Max => {
gl::BlendEquation(gl::MAX); ck();
}
}
gl::BlendFuncSeparate(blend.src_rgb_factor.to_gl_blend_factor(),
blend.dest_rgb_factor.to_gl_blend_factor(),
blend.src_alpha_factor.to_gl_blend_factor(),
blend.dest_alpha_factor.to_gl_blend_factor()); ck();
gl::BlendEquation(blend.op.to_gl_blend_op()); ck();
gl::Enable(gl::BLEND); ck();
}
}
@ -982,6 +953,39 @@ impl Drop for GLTimerQuery {
}
}
trait BlendFactorExt {
fn to_gl_blend_factor(self) -> GLenum;
}
impl BlendFactorExt for BlendFactor {
#[inline]
fn to_gl_blend_factor(self) -> GLenum {
match self {
BlendFactor::Zero => gl::ZERO,
BlendFactor::One => gl::ONE,
BlendFactor::SrcAlpha => gl::SRC_ALPHA,
BlendFactor::OneMinusSrcAlpha => gl::ONE_MINUS_SRC_ALPHA,
}
}
}
trait BlendOpExt {
fn to_gl_blend_op(self) -> GLenum;
}
impl BlendOpExt for BlendOp {
#[inline]
fn to_gl_blend_op(self) -> GLenum {
match self {
BlendOp::Add => gl::FUNC_ADD,
BlendOp::Subtract => gl::FUNC_SUBTRACT,
BlendOp::ReverseSubtract => gl::FUNC_REVERSE_SUBTRACT,
BlendOp::Min => gl::MIN,
BlendOp::Max => gl::MAX,
}
}
}
trait BufferTargetExt {
fn to_gl_target(self) -> GLuint;
}

View File

@ -211,17 +211,21 @@ pub enum RenderTarget<'a, D> where D: Device {
Framebuffer(&'a D::Framebuffer),
}
#[derive(Clone, Copy, Debug, PartialEq, Default)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct BlendState {
pub func: BlendFunc,
pub dest_rgb_factor: BlendFactor,
pub dest_alpha_factor: BlendFactor,
pub src_rgb_factor: BlendFactor,
pub src_alpha_factor: BlendFactor,
pub op: BlendOp,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum BlendFunc {
RGBOneAlphaOne,
RGBOneAlphaOneMinusSrcAlpha,
RGBSrcAlphaAlphaOneMinusSrcAlpha,
pub enum BlendFactor {
Zero,
One,
SrcAlpha,
OneMinusSrcAlpha,
}
#[derive(Clone, Copy, Debug, PartialEq)]
@ -272,13 +276,6 @@ impl Default for RenderOptions {
}
}
impl Default for BlendFunc {
#[inline]
fn default() -> BlendFunc {
BlendFunc::RGBOneAlphaOneMinusSrcAlpha
}
}
impl Default for BlendOp {
#[inline]
fn default() -> BlendOp {
@ -380,6 +377,19 @@ impl ClearOps {
}
}
impl Default for BlendState {
#[inline]
fn default() -> BlendState {
BlendState {
src_rgb_factor: BlendFactor::One,
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
src_alpha_factor: BlendFactor::One,
dest_alpha_factor: BlendFactor::One,
op: BlendOp::Add,
}
}
}
impl<'a> TextureDataRef<'a> {
#[doc(hidden)]
pub fn check_and_extract_data_ptr(self, minimum_size: Vector2I, format: TextureFormat)

View File

@ -44,7 +44,7 @@ use objc::runtime::{Class, Object};
use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::vector::Vector2I;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::{BlendFunc, BlendOp, BufferData, BufferTarget, BufferUploadMode, DepthFunc};
use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode, DepthFunc};
use pathfinder_gpu::{Device, Primitive, RenderState, RenderTarget, ShaderKind, StencilFunc};
use pathfinder_gpu::{TextureData, TextureDataRef, TextureFormat, UniformData, VertexAttrClass};
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
@ -993,45 +993,17 @@ impl MetalDevice {
None => pipeline_color_attachment.set_blending_enabled(false),
Some(ref blend) => {
pipeline_color_attachment.set_blending_enabled(true);
match blend.func {
BlendFunc::RGBOneAlphaOne => {
pipeline_color_attachment.set_source_rgb_blend_factor(MTLBlendFactor::One);
pipeline_color_attachment.set_destination_rgb_blend_factor(
MTLBlendFactor::One);
pipeline_color_attachment.set_source_alpha_blend_factor(
MTLBlendFactor::One);
pipeline_color_attachment.set_destination_alpha_blend_factor(
MTLBlendFactor::One);
}
BlendFunc::RGBOneAlphaOneMinusSrcAlpha => {
pipeline_color_attachment.set_source_rgb_blend_factor(MTLBlendFactor::One);
pipeline_color_attachment.set_destination_rgb_blend_factor(
MTLBlendFactor::OneMinusSourceAlpha);
pipeline_color_attachment.set_source_alpha_blend_factor(
MTLBlendFactor::One);
pipeline_color_attachment.set_destination_alpha_blend_factor(
MTLBlendFactor::One);
}
BlendFunc::RGBSrcAlphaAlphaOneMinusSrcAlpha => {
pipeline_color_attachment.set_source_rgb_blend_factor(
MTLBlendFactor::SourceAlpha);
pipeline_color_attachment.set_destination_rgb_blend_factor(
MTLBlendFactor::OneMinusSourceAlpha);
pipeline_color_attachment.set_source_alpha_blend_factor(
MTLBlendFactor::One);
pipeline_color_attachment.set_destination_alpha_blend_factor(
MTLBlendFactor::One);
}
}
let blend_op = match blend.op {
BlendOp::Add => MTLBlendOperation::Add,
BlendOp::Subtract => MTLBlendOperation::Subtract,
BlendOp::ReverseSubtract => MTLBlendOperation::ReverseSubtract,
BlendOp::Min => MTLBlendOperation::Min,
BlendOp::Max => MTLBlendOperation::Max,
};
pipeline_color_attachment.set_source_rgb_blend_factor(
blend.src_rgb_factor.to_metal_blend_factor());
pipeline_color_attachment.set_destination_rgb_blend_factor(
blend.dest_rgb_factor.to_metal_blend_factor());
pipeline_color_attachment.set_source_alpha_blend_factor(
blend.src_alpha_factor.to_metal_blend_factor());
pipeline_color_attachment.set_destination_alpha_blend_factor(
blend.dest_alpha_factor.to_metal_blend_factor());
let blend_op = blend.op.to_metal_blend_op();
pipeline_color_attachment.set_rgb_blend_operation(blend_op);
pipeline_color_attachment.set_alpha_blend_operation(blend_op);
}
@ -1186,6 +1158,39 @@ impl DeviceExtra for metal::Device {
// Conversion helpers
trait BlendFactorExt {
fn to_metal_blend_factor(self) -> MTLBlendFactor;
}
impl BlendFactorExt for BlendFactor {
#[inline]
fn to_metal_blend_factor(self) -> MTLBlendFactor {
match self {
BlendFactor::Zero => MTLBlendFactor::Zero,
BlendFactor::One => MTLBlendFactor::One,
BlendFactor::SrcAlpha => MTLBlendFactor::SourceAlpha,
BlendFactor::OneMinusSrcAlpha => MTLBlendFactor::OneMinusSourceAlpha,
}
}
}
trait BlendOpExt {
fn to_metal_blend_op(self) -> MTLBlendOperation;
}
impl BlendOpExt for BlendOp {
#[inline]
fn to_metal_blend_op(self) -> MTLBlendOperation {
match self {
BlendOp::Add => MTLBlendOperation::Add,
BlendOp::Subtract => MTLBlendOperation::Subtract,
BlendOp::ReverseSubtract => MTLBlendOperation::ReverseSubtract,
BlendOp::Min => MTLBlendOperation::Min,
BlendOp::Max => MTLBlendOperation::Max,
}
}
}
trait DepthFuncExt {
fn to_metal_compare_function(self) -> MTLCompareFunction;
}

View File

@ -26,7 +26,7 @@ use pathfinder_geometry::vector::{Vector2I, Vector4F};
use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::transform3d::Transform4F;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::{BlendFunc, BlendOp, BlendState, BufferData, BufferTarget, BufferUploadMode};
use pathfinder_gpu::{BlendFactor, BlendOp, BlendState, BufferData, BufferTarget, BufferUploadMode};
use pathfinder_gpu::{ClearOps, DepthFunc, DepthState, Device, Primitive, RenderOptions};
use pathfinder_gpu::{RenderState, RenderTarget, StencilFunc, StencilState, TextureDataRef};
use pathfinder_gpu::{TextureFormat, UniformData};
@ -525,7 +525,10 @@ where
viewport: self.mask_viewport(),
options: RenderOptions {
blend: Some(BlendState {
func: BlendFunc::RGBOneAlphaOne,
src_rgb_factor: BlendFactor::One,
src_alpha_factor: BlendFactor::One,
dest_rgb_factor: BlendFactor::One,
dest_alpha_factor: BlendFactor::One,
..BlendState::default()
}),
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
@ -577,7 +580,10 @@ where
viewport: self.mask_viewport(),
options: RenderOptions {
blend: Some(BlendState {
func: BlendFunc::RGBOneAlphaOne,
src_rgb_factor: BlendFactor::One,
src_alpha_factor: BlendFactor::One,
dest_rgb_factor: BlendFactor::One,
dest_alpha_factor: BlendFactor::One,
op: BlendOp::Min,
..BlendState::default()
}),
@ -623,10 +629,7 @@ where
uniforms: &uniforms,
viewport: self.draw_viewport(),
options: RenderOptions {
blend: Some(BlendState {
func: BlendFunc::RGBSrcAlphaAlphaOneMinusSrcAlpha,
..BlendState::default()
}),
blend: Some(alpha_blend_state()),
stencil: self.stencil_state(),
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
..RenderOptions::default()
@ -740,10 +743,7 @@ where
],
viewport: self.draw_viewport(),
options: RenderOptions {
blend: Some(BlendState {
func: BlendFunc::RGBSrcAlphaAlphaOneMinusSrcAlpha,
..BlendState::default()
}),
blend: Some(alpha_blend_state()),
depth: Some(DepthState { func: DepthFunc::Less, write: false, }),
clear_ops: ClearOps { color: clear_color, ..ClearOps::default() },
..RenderOptions::default()
@ -829,12 +829,7 @@ where
];
let blend_state = match composite_op {
CompositeOp::SourceOver => {
BlendState {
func: BlendFunc::RGBSrcAlphaAlphaOneMinusSrcAlpha,
..BlendState::default()
}
}
CompositeOp::SourceOver => alpha_blend_state(),
};
self.device.draw_elements(6, &RenderState {
@ -1111,3 +1106,13 @@ struct LayerFramebufferInfo<D> where D: Device {
effects: Effects,
must_preserve_contents: bool,
}
fn alpha_blend_state() -> BlendState {
BlendState {
src_rgb_factor: BlendFactor::SrcAlpha,
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
src_alpha_factor: BlendFactor::One,
dest_alpha_factor: BlendFactor::One,
..BlendState::default()
}
}

View File

@ -1,6 +1,6 @@
// pathfinder/ui/src/lib.rs
//
// Copyright © 2019 The Pathfinder Project Developers.
// Copyright © 2020 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
@ -21,7 +21,7 @@ use pathfinder_color::ColorU;
use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::vector::{Vector2F, Vector2I};
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::{BlendFunc, BlendState, BufferData, BufferTarget, BufferUploadMode, Device};
use pathfinder_gpu::{BlendFactor, BlendState, BufferData, BufferTarget, BufferUploadMode, Device};
use pathfinder_gpu::{Primitive, RenderOptions, RenderState, RenderTarget, UniformData};
use pathfinder_gpu::{VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
use pathfinder_simd::default::F32x4;
@ -187,10 +187,7 @@ impl<D> UIPresenter<D> where D: Device {
textures: &[],
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
options: RenderOptions {
blend: Some(BlendState {
func: BlendFunc::RGBOneAlphaOneMinusSrcAlpha,
..BlendState::default()
}),
blend: Some(alpha_blend_state()),
..RenderOptions::default()
},
});
@ -425,10 +422,7 @@ impl<D> UIPresenter<D> where D: Device {
],
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
options: RenderOptions {
blend: Some(BlendState {
func: BlendFunc::RGBOneAlphaOneMinusSrcAlpha,
..BlendState::default()
}),
blend: Some(alpha_blend_state()),
..RenderOptions::default()
},
});
@ -830,3 +824,13 @@ impl DebugFont {
serde_json::from_slice(&resources.slurp(FONT_JSON_VIRTUAL_PATH).unwrap()).unwrap()
}
}
fn alpha_blend_state() -> BlendState {
BlendState {
src_rgb_factor: BlendFactor::One,
dest_rgb_factor: BlendFactor::OneMinusSrcAlpha,
src_alpha_factor: BlendFactor::One,
dest_alpha_factor: BlendFactor::One,
..BlendState::default()
}
}