зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1555483 - Part 2: Add SVG filter picture composite mode r=gw
Differential Revision: https://phabricator.services.mozilla.com/D34088 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
f48188d4e6
Коммит
cc5163e0bb
|
@ -1640,6 +1640,38 @@ impl BatchBuilder {
|
|||
ctx,
|
||||
);
|
||||
}
|
||||
PictureCompositeMode::SvgFilter(..) => {
|
||||
let kind = BatchKind::Brush(
|
||||
BrushBatchKind::Image(ImageBufferKind::Texture2DArray)
|
||||
);
|
||||
let (uv_rect_address, textures) = render_tasks.resolve_surface(
|
||||
surface_task.expect("bug: surface must be allocated by now"),
|
||||
gpu_cache,
|
||||
);
|
||||
let key = BatchKey::new(
|
||||
kind,
|
||||
non_segmented_blend_mode,
|
||||
textures,
|
||||
);
|
||||
let prim_header_index = prim_headers.push(&prim_header, z_id, [
|
||||
ShaderColorMode::Image as i32 | ((AlphaType::PremultipliedAlpha as i32) << 16),
|
||||
RasterizationSpace::Screen as i32,
|
||||
get_shader_opacity(1.0),
|
||||
0,
|
||||
]);
|
||||
|
||||
self.add_brush_instance_to_batches(
|
||||
key,
|
||||
bounding_rect,
|
||||
z_id,
|
||||
INVALID_SEGMENT_INDEX,
|
||||
EdgeAaSegmentMask::empty(),
|
||||
clip_task_address,
|
||||
brush_flags,
|
||||
prim_header_index,
|
||||
uv_rect_address.as_int(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
|
|
|
@ -1981,6 +1981,48 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
self.prim_store.optimize_picture_if_possible(current_pic_index);
|
||||
}
|
||||
|
||||
if !stacking_context.composite_ops.filter_primitives.is_empty() {
|
||||
let composite_mode = PictureCompositeMode::SvgFilter(stacking_context.composite_ops.filter_primitives.clone());
|
||||
|
||||
let filter_pic_index = PictureIndex(self.prim_store.pictures
|
||||
.alloc()
|
||||
.init(PicturePrimitive::new_image(
|
||||
Some(composite_mode.clone()),
|
||||
Picture3DContext::Out,
|
||||
stacking_context.pipeline_id,
|
||||
None,
|
||||
true,
|
||||
stacking_context.is_backface_visible,
|
||||
stacking_context.requested_raster_space,
|
||||
PrimitiveList::new(
|
||||
vec![cur_instance.clone()],
|
||||
&self.interners,
|
||||
),
|
||||
stacking_context.spatial_node_index,
|
||||
None,
|
||||
PictureOptions::default(),
|
||||
))
|
||||
);
|
||||
|
||||
current_pic_index = filter_pic_index;
|
||||
cur_instance = create_prim_instance(
|
||||
current_pic_index,
|
||||
Some(composite_mode).into(),
|
||||
stacking_context.is_backface_visible,
|
||||
ClipChainId::NONE,
|
||||
stacking_context.spatial_node_index,
|
||||
&mut self.interners,
|
||||
);
|
||||
|
||||
if cur_instance.is_chased() {
|
||||
println!("\tis a composite picture for a stacking context with an SVG filter");
|
||||
}
|
||||
|
||||
// Run the optimize pass on this picture, to see if we can
|
||||
// collapse opacity and avoid drawing to an off-screen surface.
|
||||
self.prim_store.optimize_picture_if_possible(current_pic_index);
|
||||
}
|
||||
|
||||
// Same for mix-blend-mode, except we can skip if this primitive is the first in the parent
|
||||
// stacking context.
|
||||
// From https://drafts.fxtf.org/compositing-1/#generalformula, the formula for blending is:
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{MixBlendMode, PipelineId, PremultipliedColorF};
|
||||
use api::{PropertyBinding, PropertyBindingId, FontRenderMode};
|
||||
use api::{PropertyBinding, PropertyBindingId, FilterPrimitive, FontRenderMode};
|
||||
use api::{DebugFlags, RasterSpace, ImageKey, ColorF};
|
||||
use api::units::*;
|
||||
use crate::box_shadow::{BLUR_SAMPLE_SCALE};
|
||||
|
@ -1573,6 +1573,8 @@ pub enum PictureCompositeMode {
|
|||
/// Used to cache a picture as a series of tiles.
|
||||
TileCache {
|
||||
},
|
||||
/// Apply an SVG filter
|
||||
SvgFilter(Vec<FilterPrimitive>),
|
||||
}
|
||||
|
||||
/// Enum value describing the place of a picture in a 3D context.
|
||||
|
@ -1938,7 +1940,8 @@ impl PicturePrimitive {
|
|||
Some(RasterConfig { composite_mode: PictureCompositeMode::MixBlend(..), .. }) |
|
||||
Some(RasterConfig { composite_mode: PictureCompositeMode::Filter(..), .. }) |
|
||||
Some(RasterConfig { composite_mode: PictureCompositeMode::ComponentTransferFilter(..), .. }) |
|
||||
Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, ..}) |
|
||||
Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, .. }) |
|
||||
Some(RasterConfig { composite_mode: PictureCompositeMode::SvgFilter(..), .. }) |
|
||||
None => {
|
||||
false
|
||||
}
|
||||
|
@ -2442,6 +2445,30 @@ impl PicturePrimitive {
|
|||
|
||||
Some((render_task_id, render_task_id))
|
||||
}
|
||||
PictureCompositeMode::SvgFilter(..) => {
|
||||
let uv_rect_kind = calculate_uv_rect_kind(
|
||||
&pic_rect,
|
||||
&transform,
|
||||
&clipped,
|
||||
device_pixel_scale,
|
||||
true,
|
||||
);
|
||||
|
||||
let picture_task = RenderTask::new_picture(
|
||||
RenderTaskLocation::Dynamic(None, clipped.size),
|
||||
unclipped.size,
|
||||
pic_index,
|
||||
clipped.origin,
|
||||
uv_rect_kind,
|
||||
raster_spatial_node_index,
|
||||
surface_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
);
|
||||
|
||||
let render_task_id = frame_state.render_tasks.add(picture_task);
|
||||
|
||||
(render_task_id, render_task_id)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some((root, port)) = dep_info {
|
||||
|
@ -2990,7 +3017,8 @@ impl PicturePrimitive {
|
|||
filter_data.update(frame_state);
|
||||
}
|
||||
PictureCompositeMode::MixBlend(..) |
|
||||
PictureCompositeMode::Blit(_) => {}
|
||||
PictureCompositeMode::Blit(_) |
|
||||
PictureCompositeMode::SvgFilter(_) => {}
|
||||
}
|
||||
|
||||
true
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{
|
||||
ColorU, MixBlendMode,
|
||||
ColorU, MixBlendMode, FilterPrimitive,
|
||||
PropertyBinding, PropertyBindingId,
|
||||
};
|
||||
use api::units::{Au, LayoutSize, LayoutVector2D};
|
||||
|
@ -44,6 +44,7 @@ pub enum PictureCompositeKey {
|
|||
LinearToSrgb,
|
||||
ComponentTransfer(ItemUid),
|
||||
Flood(ColorU),
|
||||
SvgFilter(Vec<FilterPrimitive>),
|
||||
|
||||
// MixBlendMode
|
||||
Multiply,
|
||||
|
@ -130,6 +131,9 @@ impl From<Option<PictureCompositeMode>> for PictureCompositeKey {
|
|||
Some(PictureCompositeMode::ComponentTransferFilter(handle)) => {
|
||||
PictureCompositeKey::ComponentTransfer(handle.uid())
|
||||
}
|
||||
Some(PictureCompositeMode::SvgFilter(filter_primitives)) => {
|
||||
PictureCompositeKey::SvgFilter(filter_primitives)
|
||||
}
|
||||
Some(PictureCompositeMode::Blit(_)) |
|
||||
Some(PictureCompositeMode::TileCache { .. }) |
|
||||
None => {
|
||||
|
|
|
@ -679,7 +679,7 @@ impl RasterSpace {
|
|||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||
pub enum MixBlendMode {
|
||||
Normal = 0,
|
||||
Multiply = 1,
|
||||
|
@ -701,7 +701,7 @@ pub enum MixBlendMode {
|
|||
|
||||
/// An input to a SVG filter primitive.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||
pub enum FilterPrimitiveInput {
|
||||
/// The input is the original graphic that the filter is being applied to.
|
||||
Original,
|
||||
|
@ -712,7 +712,7 @@ pub enum FilterPrimitiveInput {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||
pub struct BlendPrimitive {
|
||||
pub input1: FilterPrimitiveInput,
|
||||
pub input2: FilterPrimitiveInput,
|
||||
|
@ -721,7 +721,7 @@ pub struct BlendPrimitive {
|
|||
|
||||
/// SVG Filter Primitive.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
||||
pub enum FilterPrimitive {
|
||||
Blend(BlendPrimitive),
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче