зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1505871. Write component transfer filter data into the webrender display list bitstream. r=jrmuizel
The format for stacking contexts in the built display list goes from PushStackingContext item push_iter of Vec<FilterOp> to SetFilterOps item push_iter of Vec<FilterOp> 1st SetFilterData item push_iter of array of func types push_iter funcR values push_iter funcG values push_iter funcB values push_iter funcA values . . . nth SetFilterData item push_iter of array of func types push_iter funcR values push_iter funcG values push_iter funcB values push_iter funcA values PushStackingContext item We need separate a SetFilterData item for each filter because we can't push_iter a variable sized thing. When we iterate over the built display list to flatten it we work similarly to how gradients work with a SetGradientStops item before the actual gradient item. So when we see SetFilterOps or SetFilterData we use them to fill out values on the built display list iterator but don't those items return them to the iterator user and instead continue iterating until we hit the PushStackingContext item, at which point to the iterator consumer it appears as those the FilterOps and FilterDatas were on the PushStackingContext item. (This part is trickier too since we need a TempFilterData type that just holds ItemRange's until we get the actual bytes later.) Do we need to clear cur_filters and cur_filter_data at some point to prevent them from getting ready by items for which they do not apply?
This commit is contained in:
Родитель
b9d0354d8a
Коммит
5455bb5b62
|
@ -1981,6 +1981,20 @@ pub extern "C" fn wr_dp_push_stacking_context(
|
||||||
*c_filter
|
*c_filter
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
|
let c_filter_datas = make_slice(filter_datas, filter_datas_count);
|
||||||
|
let r_filter_datas : Vec<FilterData> = c_filter_datas.iter().map(|c_filter_data| {
|
||||||
|
FilterData {
|
||||||
|
func_r_type: c_filter_data.funcR_type,
|
||||||
|
r_values: make_slice(c_filter_data.R_values, c_filter_data.R_values_count).to_vec(),
|
||||||
|
func_g_type: c_filter_data.funcG_type,
|
||||||
|
g_values: make_slice(c_filter_data.G_values, c_filter_data.G_values_count).to_vec(),
|
||||||
|
func_b_type: c_filter_data.funcB_type,
|
||||||
|
b_values: make_slice(c_filter_data.B_values, c_filter_data.B_values_count).to_vec(),
|
||||||
|
func_a_type: c_filter_data.funcA_type,
|
||||||
|
a_values: make_slice(c_filter_data.A_values, c_filter_data.A_values_count).to_vec(),
|
||||||
|
}
|
||||||
|
}).collect();
|
||||||
|
|
||||||
let transform_ref = unsafe { transform.as_ref() };
|
let transform_ref = unsafe { transform.as_ref() };
|
||||||
let mut transform_binding = match transform_ref {
|
let mut transform_binding = match transform_ref {
|
||||||
Some(t) => Some(PropertyBinding::Value(t.clone())),
|
Some(t) => Some(PropertyBinding::Value(t.clone())),
|
||||||
|
@ -2068,6 +2082,7 @@ pub extern "C" fn wr_dp_push_stacking_context(
|
||||||
params.transform_style,
|
params.transform_style,
|
||||||
params.mix_blend_mode,
|
params.mix_blend_mode,
|
||||||
&filters,
|
&filters,
|
||||||
|
&r_filter_datas,
|
||||||
glyph_raster_space,
|
glyph_raster_space,
|
||||||
params.cache_tiles);
|
params.cache_tiles);
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ impl App {
|
||||||
&LayoutPrimitiveInfo::new(LayoutRect::zero()),
|
&LayoutPrimitiveInfo::new(LayoutRect::zero()),
|
||||||
spatial_id,
|
spatial_id,
|
||||||
&filters,
|
&filters,
|
||||||
|
&[],
|
||||||
);
|
);
|
||||||
|
|
||||||
let space_and_clip = SpaceAndClipInfo {
|
let space_and_clip = SpaceAndClipInfo {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use api::{LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVe
|
||||||
use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId};
|
use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId};
|
||||||
use api::{PropertyBinding, ReferenceFrame, ReferenceFrameKind, ScrollFrameDisplayItem, ScrollSensitivity};
|
use api::{PropertyBinding, ReferenceFrame, ReferenceFrameKind, ScrollFrameDisplayItem, ScrollSensitivity};
|
||||||
use api::{Shadow, SpaceAndClipInfo, SpatialId, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect};
|
use api::{Shadow, SpaceAndClipInfo, SpatialId, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, TexelRect};
|
||||||
use api::{ClipMode, TransformStyle, YuvColorSpace, YuvData};
|
use api::{ClipMode, TransformStyle, YuvColorSpace, YuvData, TempFilterData};
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore};
|
use clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore};
|
||||||
use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex};
|
use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex};
|
||||||
|
@ -592,6 +592,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
spatial_node_index: SpatialNodeIndex,
|
spatial_node_index: SpatialNodeIndex,
|
||||||
origin: LayoutPoint,
|
origin: LayoutPoint,
|
||||||
filters: ItemRange<FilterOp>,
|
filters: ItemRange<FilterOp>,
|
||||||
|
filter_datas: &[TempFilterData],
|
||||||
reference_frame_relative_offset: &LayoutVector2D,
|
reference_frame_relative_offset: &LayoutVector2D,
|
||||||
is_backface_visible: bool,
|
is_backface_visible: bool,
|
||||||
apply_pipeline_clip: bool,
|
apply_pipeline_clip: bool,
|
||||||
|
@ -880,6 +881,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
clip_and_scroll.spatial_node_index,
|
clip_and_scroll.spatial_node_index,
|
||||||
item.rect().origin,
|
item.rect().origin,
|
||||||
item.filters(),
|
item.filters(),
|
||||||
|
item.filter_datas(),
|
||||||
&reference_frame_relative_offset,
|
&reference_frame_relative_offset,
|
||||||
prim_info.is_backface_visible,
|
prim_info.is_backface_visible,
|
||||||
apply_pipeline_clip,
|
apply_pipeline_clip,
|
||||||
|
@ -1006,6 +1008,8 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
|
|
||||||
// Do nothing; these are dummy items for the display list parser
|
// Do nothing; these are dummy items for the display list parser
|
||||||
SpecificDisplayItem::SetGradientStops => {}
|
SpecificDisplayItem::SetGradientStops => {}
|
||||||
|
SpecificDisplayItem::SetFilterOps => {}
|
||||||
|
SpecificDisplayItem::SetFilterData => {}
|
||||||
|
|
||||||
SpecificDisplayItem::PopReferenceFrame |
|
SpecificDisplayItem::PopReferenceFrame |
|
||||||
SpecificDisplayItem::PopStackingContext => {
|
SpecificDisplayItem::PopStackingContext => {
|
||||||
|
|
|
@ -1593,6 +1593,8 @@ impl ToDebugString for SpecificDisplayItem {
|
||||||
SpecificDisplayItem::PushShadow(..) => String::from("push_shadow"),
|
SpecificDisplayItem::PushShadow(..) => String::from("push_shadow"),
|
||||||
SpecificDisplayItem::PushReferenceFrame(..) => String::from("push_reference_frame"),
|
SpecificDisplayItem::PushReferenceFrame(..) => String::from("push_reference_frame"),
|
||||||
SpecificDisplayItem::PushStackingContext(..) => String::from("push_stacking_context"),
|
SpecificDisplayItem::PushStackingContext(..) => String::from("push_stacking_context"),
|
||||||
|
SpecificDisplayItem::SetFilterOps => String::from("set_filter_ops"),
|
||||||
|
SpecificDisplayItem::SetFilterData => String::from("set_filter_data"),
|
||||||
SpecificDisplayItem::RadialGradient(..) => String::from("radial_gradient"),
|
SpecificDisplayItem::RadialGradient(..) => String::from("radial_gradient"),
|
||||||
SpecificDisplayItem::Rectangle(..) => String::from("rectangle"),
|
SpecificDisplayItem::Rectangle(..) => String::from("rectangle"),
|
||||||
SpecificDisplayItem::ScrollFrame(..) => String::from("scroll_frame"),
|
SpecificDisplayItem::ScrollFrame(..) => String::from("scroll_frame"),
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use api::{BuiltDisplayList, ColorF, DynamicProperties, Epoch, LayoutSize};
|
use api::{BuiltDisplayList, ColorF, DynamicProperties, Epoch, LayoutSize};
|
||||||
use api::{FilterOp, LayoutTransform, PipelineId, PropertyBinding, PropertyBindingId};
|
use api::{FilterOp, TempFilterData, FilterData, ComponentTransferFuncType, LayoutTransform};
|
||||||
use api::{ItemRange, MixBlendMode, StackingContext};
|
use api::{PipelineId, PropertyBinding, PropertyBindingId, ItemRange, MixBlendMode, StackingContext};
|
||||||
use internal_types::FastHashMap;
|
use internal_types::FastHashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -225,7 +225,8 @@ impl FilterOpHelpers for FilterOp {
|
||||||
FilterOp::DropShadow(..) |
|
FilterOp::DropShadow(..) |
|
||||||
FilterOp::ColorMatrix(..) |
|
FilterOp::ColorMatrix(..) |
|
||||||
FilterOp::SrgbToLinear |
|
FilterOp::SrgbToLinear |
|
||||||
FilterOp::LinearToSrgb => true,
|
FilterOp::LinearToSrgb |
|
||||||
|
FilterOp::ComponentTransfer => true,
|
||||||
FilterOp::Opacity(_, amount) => {
|
FilterOp::Opacity(_, amount) => {
|
||||||
amount > OPACITY_EPSILON
|
amount > OPACITY_EPSILON
|
||||||
}
|
}
|
||||||
|
@ -254,7 +255,9 @@ impl FilterOpHelpers for FilterOp {
|
||||||
0.0, 0.0, 0.0, 1.0,
|
0.0, 0.0, 0.0, 1.0,
|
||||||
0.0, 0.0, 0.0, 0.0]
|
0.0, 0.0, 0.0, 0.0]
|
||||||
}
|
}
|
||||||
FilterOp::SrgbToLinear | FilterOp::LinearToSrgb => false,
|
FilterOp::SrgbToLinear |
|
||||||
|
FilterOp::LinearToSrgb |
|
||||||
|
FilterOp::ComponentTransfer => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,6 +269,11 @@ pub trait StackingContextHelpers {
|
||||||
display_list: &BuiltDisplayList,
|
display_list: &BuiltDisplayList,
|
||||||
input_filters: ItemRange<FilterOp>,
|
input_filters: ItemRange<FilterOp>,
|
||||||
) -> Vec<FilterOp>;
|
) -> Vec<FilterOp>;
|
||||||
|
fn filter_datas_for_compositing(
|
||||||
|
&self,
|
||||||
|
display_list: &BuiltDisplayList,
|
||||||
|
input_filter_datas: &[TempFilterData],
|
||||||
|
) -> Vec<FilterData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StackingContextHelpers for StackingContext {
|
impl StackingContextHelpers for StackingContext {
|
||||||
|
@ -290,4 +298,30 @@ impl StackingContextHelpers for StackingContext {
|
||||||
}
|
}
|
||||||
filters
|
filters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn filter_datas_for_compositing(
|
||||||
|
&self,
|
||||||
|
display_list: &BuiltDisplayList,
|
||||||
|
input_filter_datas: &[TempFilterData],
|
||||||
|
) -> Vec<FilterData> {
|
||||||
|
// TODO(gw): Now that we resolve these later on,
|
||||||
|
// we could probably make it a bit
|
||||||
|
// more efficient than cloning these here.
|
||||||
|
let mut filter_datas = vec![];
|
||||||
|
for temp_filter_data in input_filter_datas {
|
||||||
|
let func_types : Vec<ComponentTransferFuncType> = display_list.get(temp_filter_data.func_types).collect();
|
||||||
|
debug_assert!(func_types.len() == 4);
|
||||||
|
filter_datas.push( FilterData {
|
||||||
|
func_r_type: func_types[0],
|
||||||
|
r_values: display_list.get(temp_filter_data.r_values).collect(),
|
||||||
|
func_g_type: func_types[1],
|
||||||
|
g_values: display_list.get(temp_filter_data.g_values).collect(),
|
||||||
|
func_b_type: func_types[2],
|
||||||
|
b_values: display_list.get(temp_filter_data.b_values).collect(),
|
||||||
|
func_a_type: func_types[3],
|
||||||
|
a_values: display_list.get(temp_filter_data.a_values).collect(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
filter_datas
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,8 @@ pub enum SpecificDisplayItem {
|
||||||
PopAllShadows,
|
PopAllShadows,
|
||||||
PushCacheMarker(CacheMarkerDisplayItem),
|
PushCacheMarker(CacheMarkerDisplayItem),
|
||||||
PopCacheMarker,
|
PopCacheMarker,
|
||||||
|
SetFilterOps,
|
||||||
|
SetFilterData,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a "complete" version of the DI specifics,
|
/// This is a "complete" version of the DI specifics,
|
||||||
|
@ -153,13 +155,15 @@ pub enum CompletelySpecificDisplayItem {
|
||||||
Iframe(IframeDisplayItem),
|
Iframe(IframeDisplayItem),
|
||||||
PushReferenceFrame(ReferenceFrameDisplayListItem),
|
PushReferenceFrame(ReferenceFrameDisplayListItem),
|
||||||
PopReferenceFrame,
|
PopReferenceFrame,
|
||||||
PushStackingContext(PushStackingContextDisplayItem, Vec<FilterOp>),
|
PushStackingContext(PushStackingContextDisplayItem),
|
||||||
PopStackingContext,
|
PopStackingContext,
|
||||||
SetGradientStops(Vec<GradientStop>),
|
SetGradientStops(Vec<GradientStop>),
|
||||||
PushShadow(Shadow),
|
PushShadow(Shadow),
|
||||||
PopAllShadows,
|
PopAllShadows,
|
||||||
PushCacheMarker(CacheMarkerDisplayItem),
|
PushCacheMarker(CacheMarkerDisplayItem),
|
||||||
PopCacheMarker,
|
PopCacheMarker,
|
||||||
|
SetFilterOps(Vec<FilterOp>),
|
||||||
|
SetFilterData(FilterData),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
|
@ -562,8 +566,7 @@ pub struct StackingContext {
|
||||||
pub raster_space: RasterSpace,
|
pub raster_space: RasterSpace,
|
||||||
/// True if picture caching should be used on this stacking context.
|
/// True if picture caching should be used on this stacking context.
|
||||||
pub cache_tiles: bool,
|
pub cache_tiles: bool,
|
||||||
} // IMPLICIT: filters: Vec<FilterOp>
|
} // IMPLICIT: filters: Vec<FilterOp>, filter_datas: Vec<FilterData>
|
||||||
|
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||||
|
@ -641,6 +644,7 @@ pub enum FilterOp {
|
||||||
ColorMatrix([f32; 20]),
|
ColorMatrix([f32; 20]),
|
||||||
SrgbToLinear,
|
SrgbToLinear,
|
||||||
LinearToSrgb,
|
LinearToSrgb,
|
||||||
|
ComponentTransfer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilterOp {
|
impl FilterOp {
|
||||||
|
@ -661,6 +665,28 @@ impl FilterOp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
|
||||||
|
pub enum ComponentTransferFuncType {
|
||||||
|
Identity = 0,
|
||||||
|
Table = 1,
|
||||||
|
Discrete = 2,
|
||||||
|
Linear = 3,
|
||||||
|
Gamma = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||||
|
pub struct FilterData {
|
||||||
|
pub func_r_type: ComponentTransferFuncType,
|
||||||
|
pub r_values: Vec<f32>,
|
||||||
|
pub func_g_type: ComponentTransferFuncType,
|
||||||
|
pub g_values: Vec<f32>,
|
||||||
|
pub func_b_type: ComponentTransferFuncType,
|
||||||
|
pub b_values: Vec<f32>,
|
||||||
|
pub func_a_type: ComponentTransferFuncType,
|
||||||
|
pub a_values: Vec<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
pub struct IframeDisplayItem {
|
pub struct IframeDisplayItem {
|
||||||
pub pipeline_id: PipelineId,
|
pub pipeline_id: PipelineId,
|
||||||
|
|
|
@ -61,6 +61,14 @@ impl<T> ItemRange<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct TempFilterData {
|
||||||
|
pub func_types: ItemRange<di::ComponentTransferFuncType>,
|
||||||
|
pub r_values: ItemRange<f32>,
|
||||||
|
pub g_values: ItemRange<f32>,
|
||||||
|
pub b_values: ItemRange<f32>,
|
||||||
|
pub a_values: ItemRange<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
/// A display list.
|
/// A display list.
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct BuiltDisplayList {
|
pub struct BuiltDisplayList {
|
||||||
|
@ -95,6 +103,7 @@ pub struct BuiltDisplayListIter<'a> {
|
||||||
cur_stops: ItemRange<di::GradientStop>,
|
cur_stops: ItemRange<di::GradientStop>,
|
||||||
cur_glyphs: ItemRange<GlyphInstance>,
|
cur_glyphs: ItemRange<GlyphInstance>,
|
||||||
cur_filters: ItemRange<di::FilterOp>,
|
cur_filters: ItemRange<di::FilterOp>,
|
||||||
|
cur_filter_data: Vec<TempFilterData>,
|
||||||
cur_clip_chain_items: ItemRange<di::ClipId>,
|
cur_clip_chain_items: ItemRange<di::ClipId>,
|
||||||
cur_complex_clip: (ItemRange<di::ComplexClipRegion>, usize),
|
cur_complex_clip: (ItemRange<di::ComplexClipRegion>, usize),
|
||||||
peeking: Peek,
|
peeking: Peek,
|
||||||
|
@ -215,6 +224,7 @@ impl<'a> BuiltDisplayListIter<'a> {
|
||||||
cur_stops: ItemRange::default(),
|
cur_stops: ItemRange::default(),
|
||||||
cur_glyphs: ItemRange::default(),
|
cur_glyphs: ItemRange::default(),
|
||||||
cur_filters: ItemRange::default(),
|
cur_filters: ItemRange::default(),
|
||||||
|
cur_filter_data: Vec::new(),
|
||||||
cur_clip_chain_items: ItemRange::default(),
|
cur_clip_chain_items: ItemRange::default(),
|
||||||
cur_complex_clip: (ItemRange::default(), 0),
|
cur_complex_clip: (ItemRange::default(), 0),
|
||||||
peeking: Peek::NotPeeking,
|
peeking: Peek::NotPeeking,
|
||||||
|
@ -250,6 +260,15 @@ impl<'a> BuiltDisplayListIter<'a> {
|
||||||
// SetGradientStops is a dummy item that most consumers should ignore
|
// SetGradientStops is a dummy item that most consumers should ignore
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if let SetFilterOps = self.cur_item.item {
|
||||||
|
// SetFilterOps is a dummy item that most consumers should ignore
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let SetFilterData = self.cur_item.item {
|
||||||
|
// SetFilterData is a dummy item that most consumers should ignore
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,6 +295,18 @@ impl<'a> BuiltDisplayListIter<'a> {
|
||||||
SetGradientStops => {
|
SetGradientStops => {
|
||||||
self.cur_stops = skip_slice::<di::GradientStop>(self.list, &mut self.data).0;
|
self.cur_stops = skip_slice::<di::GradientStop>(self.list, &mut self.data).0;
|
||||||
}
|
}
|
||||||
|
SetFilterOps => {
|
||||||
|
self.cur_filters = skip_slice::<di::FilterOp>(self.list, &mut self.data).0;
|
||||||
|
}
|
||||||
|
SetFilterData => {
|
||||||
|
self.cur_filter_data.push(TempFilterData {
|
||||||
|
func_types: skip_slice::<di::ComponentTransferFuncType>(self.list, &mut self.data).0,
|
||||||
|
r_values: skip_slice::<f32>(self.list, &mut self.data).0,
|
||||||
|
g_values: skip_slice::<f32>(self.list, &mut self.data).0,
|
||||||
|
b_values: skip_slice::<f32>(self.list, &mut self.data).0,
|
||||||
|
a_values: skip_slice::<f32>(self.list, &mut self.data).0,
|
||||||
|
});
|
||||||
|
}
|
||||||
ClipChain(_) => {
|
ClipChain(_) => {
|
||||||
self.cur_clip_chain_items = skip_slice::<di::ClipId>(self.list, &mut self.data).0;
|
self.cur_clip_chain_items = skip_slice::<di::ClipId>(self.list, &mut self.data).0;
|
||||||
}
|
}
|
||||||
|
@ -283,7 +314,6 @@ impl<'a> BuiltDisplayListIter<'a> {
|
||||||
self.cur_complex_clip = self.skip_slice::<di::ComplexClipRegion>()
|
self.cur_complex_clip = self.skip_slice::<di::ComplexClipRegion>()
|
||||||
}
|
}
|
||||||
Text(_) => self.cur_glyphs = self.skip_slice::<GlyphInstance>().0,
|
Text(_) => self.cur_glyphs = self.skip_slice::<GlyphInstance>().0,
|
||||||
PushStackingContext(_) => self.cur_filters = self.skip_slice::<di::FilterOp>().0,
|
|
||||||
_ => { /* do nothing */ }
|
_ => { /* do nothing */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,6 +419,10 @@ impl<'a, 'b> DisplayItemRef<'a, 'b> {
|
||||||
self.iter.cur_filters
|
self.iter.cur_filters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn filter_datas(&self) -> &Vec<TempFilterData> {
|
||||||
|
&self.iter.cur_filter_data
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clip_chain_items(&self) -> ItemRange<di::ClipId> {
|
pub fn clip_chain_items(&self) -> ItemRange<di::ClipId> {
|
||||||
self.iter.cur_clip_chain_items
|
self.iter.cur_clip_chain_items
|
||||||
}
|
}
|
||||||
|
@ -487,11 +521,29 @@ impl Serialize for BuiltDisplayList {
|
||||||
di::SpecificDisplayItem::Iframe(v) => Iframe(v),
|
di::SpecificDisplayItem::Iframe(v) => Iframe(v),
|
||||||
di::SpecificDisplayItem::PushReferenceFrame(v) => PushReferenceFrame(v),
|
di::SpecificDisplayItem::PushReferenceFrame(v) => PushReferenceFrame(v),
|
||||||
di::SpecificDisplayItem::PopReferenceFrame => PopReferenceFrame,
|
di::SpecificDisplayItem::PopReferenceFrame => PopReferenceFrame,
|
||||||
di::SpecificDisplayItem::PushStackingContext(v) => PushStackingContext(
|
di::SpecificDisplayItem::PushStackingContext(v) => PushStackingContext(v),
|
||||||
v,
|
di::SpecificDisplayItem::PopStackingContext => PopStackingContext,
|
||||||
|
di::SpecificDisplayItem::SetFilterOps => SetFilterOps(
|
||||||
item.iter.list.get(item.iter.cur_filters).collect()
|
item.iter.list.get(item.iter.cur_filters).collect()
|
||||||
),
|
),
|
||||||
di::SpecificDisplayItem::PopStackingContext => PopStackingContext,
|
di::SpecificDisplayItem::SetFilterData => {
|
||||||
|
debug_assert!(!item.iter.cur_filter_data.is_empty());
|
||||||
|
let temp_filter_data = &item.iter.cur_filter_data[item.iter.cur_filter_data.len()-1];
|
||||||
|
|
||||||
|
let func_types: Vec<di::ComponentTransferFuncType> =
|
||||||
|
item.iter.list.get(temp_filter_data.func_types).collect();
|
||||||
|
debug_assert!(func_types.len() == 4);
|
||||||
|
SetFilterData(di::FilterData {
|
||||||
|
func_r_type: func_types[0],
|
||||||
|
r_values: item.iter.list.get(temp_filter_data.r_values).collect(),
|
||||||
|
func_g_type: func_types[1],
|
||||||
|
g_values: item.iter.list.get(temp_filter_data.g_values).collect(),
|
||||||
|
func_b_type: func_types[2],
|
||||||
|
b_values: item.iter.list.get(temp_filter_data.b_values).collect(),
|
||||||
|
func_a_type: func_types[3],
|
||||||
|
a_values: item.iter.list.get(temp_filter_data.a_values).collect(),
|
||||||
|
})
|
||||||
|
},
|
||||||
di::SpecificDisplayItem::SetGradientStops => SetGradientStops(
|
di::SpecificDisplayItem::SetGradientStops => SetGradientStops(
|
||||||
item.iter.list.get(item.iter.cur_stops).collect()
|
item.iter.list.get(item.iter.cur_stops).collect()
|
||||||
),
|
),
|
||||||
|
@ -574,10 +626,26 @@ impl<'de> Deserialize<'de> for BuiltDisplayList {
|
||||||
di::SpecificDisplayItem::PushReferenceFrame(v)
|
di::SpecificDisplayItem::PushReferenceFrame(v)
|
||||||
}
|
}
|
||||||
PopReferenceFrame => di::SpecificDisplayItem::PopReferenceFrame,
|
PopReferenceFrame => di::SpecificDisplayItem::PopReferenceFrame,
|
||||||
PushStackingContext(specific_item, filters) => {
|
PushStackingContext(specific_item) => {
|
||||||
DisplayListBuilder::push_iter_impl(&mut temp, filters);
|
|
||||||
di::SpecificDisplayItem::PushStackingContext(specific_item)
|
di::SpecificDisplayItem::PushStackingContext(specific_item)
|
||||||
},
|
},
|
||||||
|
SetFilterOps(filters) => {
|
||||||
|
DisplayListBuilder::push_iter_impl(&mut temp, filters);
|
||||||
|
di::SpecificDisplayItem::SetFilterOps
|
||||||
|
},
|
||||||
|
SetFilterData(filter_data) => {
|
||||||
|
let func_types: Vec<di::ComponentTransferFuncType> =
|
||||||
|
[filter_data.func_r_type,
|
||||||
|
filter_data.func_g_type,
|
||||||
|
filter_data.func_b_type,
|
||||||
|
filter_data.func_a_type].to_vec();
|
||||||
|
DisplayListBuilder::push_iter_impl(&mut temp, func_types);
|
||||||
|
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.r_values);
|
||||||
|
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.g_values);
|
||||||
|
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.b_values);
|
||||||
|
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.a_values);
|
||||||
|
di::SpecificDisplayItem::SetFilterData
|
||||||
|
},
|
||||||
PopStackingContext => di::SpecificDisplayItem::PopStackingContext,
|
PopStackingContext => di::SpecificDisplayItem::PopStackingContext,
|
||||||
SetGradientStops(stops) => {
|
SetGradientStops(stops) => {
|
||||||
DisplayListBuilder::push_iter_impl(&mut temp, stops);
|
DisplayListBuilder::push_iter_impl(&mut temp, stops);
|
||||||
|
@ -1299,9 +1367,25 @@ impl DisplayListBuilder {
|
||||||
transform_style: di::TransformStyle,
|
transform_style: di::TransformStyle,
|
||||||
mix_blend_mode: di::MixBlendMode,
|
mix_blend_mode: di::MixBlendMode,
|
||||||
filters: &[di::FilterOp],
|
filters: &[di::FilterOp],
|
||||||
|
filter_datas: &[di::FilterData],
|
||||||
raster_space: di::RasterSpace,
|
raster_space: di::RasterSpace,
|
||||||
cache_tiles: bool,
|
cache_tiles: bool,
|
||||||
) {
|
) {
|
||||||
|
self.push_new_empty_item(&di::SpecificDisplayItem::SetFilterOps);
|
||||||
|
self.push_iter(filters);
|
||||||
|
|
||||||
|
for filter_data in filter_datas {
|
||||||
|
let func_types = [
|
||||||
|
filter_data.func_r_type, filter_data.func_g_type,
|
||||||
|
filter_data.func_b_type, filter_data.func_a_type];
|
||||||
|
self.push_new_empty_item(&di::SpecificDisplayItem::SetFilterData);
|
||||||
|
self.push_iter(&func_types);
|
||||||
|
self.push_iter(&filter_data.r_values);
|
||||||
|
self.push_iter(&filter_data.g_values);
|
||||||
|
self.push_iter(&filter_data.b_values);
|
||||||
|
self.push_iter(&filter_data.a_values);
|
||||||
|
}
|
||||||
|
|
||||||
let item = di::SpecificDisplayItem::PushStackingContext(di::PushStackingContextDisplayItem {
|
let item = di::SpecificDisplayItem::PushStackingContext(di::PushStackingContextDisplayItem {
|
||||||
stacking_context: di::StackingContext {
|
stacking_context: di::StackingContext {
|
||||||
transform_style,
|
transform_style,
|
||||||
|
@ -1316,7 +1400,6 @@ impl DisplayListBuilder {
|
||||||
spatial_id,
|
spatial_id,
|
||||||
clip_id: di::ClipId::invalid(),
|
clip_id: di::ClipId::invalid(),
|
||||||
});
|
});
|
||||||
self.push_iter(filters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper for examples/ code.
|
/// Helper for examples/ code.
|
||||||
|
@ -1325,7 +1408,7 @@ impl DisplayListBuilder {
|
||||||
layout: &di::LayoutPrimitiveInfo,
|
layout: &di::LayoutPrimitiveInfo,
|
||||||
spatial_id: di::SpatialId,
|
spatial_id: di::SpatialId,
|
||||||
) {
|
) {
|
||||||
self.push_simple_stacking_context_with_filters(layout, spatial_id, &[]);
|
self.push_simple_stacking_context_with_filters(layout, spatial_id, &[], &[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper for examples/ code.
|
/// Helper for examples/ code.
|
||||||
|
@ -1334,6 +1417,7 @@ impl DisplayListBuilder {
|
||||||
layout: &di::LayoutPrimitiveInfo,
|
layout: &di::LayoutPrimitiveInfo,
|
||||||
spatial_id: di::SpatialId,
|
spatial_id: di::SpatialId,
|
||||||
filters: &[di::FilterOp],
|
filters: &[di::FilterOp],
|
||||||
|
filter_datas: &[di::FilterData],
|
||||||
) {
|
) {
|
||||||
self.push_stacking_context(
|
self.push_stacking_context(
|
||||||
layout,
|
layout,
|
||||||
|
@ -1342,6 +1426,7 @@ impl DisplayListBuilder {
|
||||||
di::TransformStyle::Flat,
|
di::TransformStyle::Flat,
|
||||||
di::MixBlendMode::Normal,
|
di::MixBlendMode::Normal,
|
||||||
filters,
|
filters,
|
||||||
|
filter_datas,
|
||||||
di::RasterSpace::Screen,
|
di::RasterSpace::Screen,
|
||||||
/* cache_tiles = */ false,
|
/* cache_tiles = */ false,
|
||||||
);
|
);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче