/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use api::{ColorF, MixBlendMode}; use api::units::*; use crate::pattern::{ Pattern, PatternBuilder, PatternBuilderContext, PatternBuilderState, PatternKind, PatternShaderInput, PatternTextureInput, }; use crate::render_task_graph::RenderTaskId; use crate::renderer::BlendMode; /// A mix-blend-mode pattern that can't be expressed with a GPU blend equation. /// Drawn via the ps_quad_mix_blend shader. /// /// The backdrop (a readback render task) is sampled from slot 0 (sColor0). /// The source (the picture's own content) is sampled from slot 1 (sColor1), its /// texture-cache rect is written to the pattern's gpu block. pub struct MixBlendPattern { pub backdrop_task_id: RenderTaskId, pub src_task_id: RenderTaskId, pub mode: MixBlendMode, } impl PatternBuilder for MixBlendPattern { fn build( &self, _sub_rect: Option, _offset: LayoutVector2D, _ctx: &PatternBuilderContext, state: &mut PatternBuilderState, ) -> Pattern { // See fetch in ps_quad_mix_blend.glsl: the source texture-cache rect, // resolved from its render task. let mut writer = state.frame_gpu_data.f32.write_blocks(1); writer.push_render_task(self.src_task_id); let addr = writer.finish(); Pattern { kind: PatternKind::MixBlend, shader_input: PatternShaderInput(addr.as_int(), self.mode as u32 as i32), texture_input: PatternTextureInput { task_ids: [self.backdrop_task_id, self.src_task_id, RenderTaskId::INVALID], }, base_color: ColorF::WHITE, is_opaque: false, blend_mode: BlendMode::PremultipliedAlpha, } } } /// A mix-blend-mode patterns that maps to a GPU blend state (potentially using /// an advanced blend equation). /// The source is drawn as a normal premultiplied image with ps_quad_textured /// and the blend mode is applied by the blend stage against the destination. pub struct FixedFunctionMixBlendPattern { pub src_task_id: RenderTaskId, pub blend_mode: BlendMode, } impl PatternBuilder for FixedFunctionMixBlendPattern { fn build( &self, _sub_rect: Option, _offset: LayoutVector2D, _ctx: &PatternBuilderContext, _state: &mut PatternBuilderState, ) -> Pattern { Pattern::texture(self.src_task_id, false).with_blend_mode(self.blend_mode) } }