From 279cda65edf1a21b2db196d7eec256e9603efffa Mon Sep 17 00:00:00 2001 From: Pyfisch Date: Sat, 10 Feb 2018 21:29:46 +0100 Subject: [PATCH] Use typed transforms in stacking contexts --- components/gfx/display_list/mod.rs | 16 +++---- components/layout/display_list/builder.rs | 16 +++---- .../layout/display_list/webrender_helpers.rs | 14 ++---- components/layout/flow.rs | 7 +-- components/layout/fragment.rs | 48 +++++++++++-------- components/layout/sequential.rs | 3 +- 6 files changed, 51 insertions(+), 53 deletions(-) diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 86da27a0e2d..bc2cad8782b 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -14,7 +14,7 @@ //! They are therefore not exactly analogous to constructs like Skia pictures, which consist of //! low-level drawing primitives. -use euclid::{Transform3D, Vector2D, TypedRect, SideOffsets2D}; +use euclid::{Vector2D, TypedRect, SideOffsets2D}; use euclid::num::{One, Zero}; use gfx_traits::{self, StackingContextId}; use gfx_traits::print_tree::PrintTree; @@ -33,8 +33,8 @@ use text::glyph::ByteIndex; use webrender_api::{BorderRadius, BorderWidths, BoxShadowClipMode, ClipMode, ColorF}; use webrender_api::{ComplexClipRegion, ExtendMode, ExternalScrollId, FilterOp, FontInstanceKey}; use webrender_api::{GlyphInstance, GradientStop, ImageBorder, ImageKey, ImageRendering}; -use webrender_api::{LayoutPoint, LayoutRect, LayoutSize, LayoutVector2D, LineStyle, LocalClip}; -use webrender_api::{MixBlendMode, NormalBorder, ScrollPolicy, ScrollSensitivity}; +use webrender_api::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D, LineStyle}; +use webrender_api::{LocalClip, MixBlendMode, NormalBorder, ScrollPolicy, ScrollSensitivity}; use webrender_api::{StickyOffsetBounds, TransformStyle}; pub use style::dom::OpaqueNode; @@ -209,13 +209,13 @@ pub struct StackingContext { pub mix_blend_mode: MixBlendMode, /// A transform to be applied to this stacking context. - pub transform: Option>, + pub transform: Option, /// The transform style of this stacking context. pub transform_style: TransformStyle, /// The perspective matrix to be applied to children. - pub perspective: Option>, + pub perspective: Option, /// The scroll policy of this layer. pub scroll_policy: ScrollPolicy, @@ -234,9 +234,9 @@ impl StackingContext { z_index: i32, filters: Vec, mix_blend_mode: MixBlendMode, - transform: Option>, + transform: Option, transform_style: TransformStyle, - perspective: Option>, + perspective: Option, scroll_policy: ScrollPolicy, parent_clipping_and_scrolling: ClippingAndScrolling) -> StackingContext { @@ -1028,7 +1028,7 @@ pub trait SimpleMatrixDetection { fn is_identity_or_simple_translation(&self) -> bool; } -impl SimpleMatrixDetection for Transform3D { +impl SimpleMatrixDetection for LayoutTransform { #[inline] fn is_identity_or_simple_translation(&self) -> bool { let (_0, _1) = (Zero::zero(), One::one()); diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index d57c663ecd5..a8853648b23 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -17,7 +17,7 @@ use context::LayoutContext; use display_list::ToLayout; use display_list::background::{compute_background_image_size, tile_image_axis}; use display_list::background::{convert_linear_gradient, convert_radial_gradient}; -use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, TypedSize2D, Vector2D, rect}; +use euclid::{rect, Point2D, Rect, SideOffsets2D, Size2D, TypedSize2D, Vector2D}; use flex::FlexFlow; use flow::{BaseFlow, Flow, FlowFlags}; use flow_ref::FlowRef; @@ -76,9 +76,9 @@ use style_traits::cursor::CursorKind; use table_cell::CollapsedBordersForCell; use webrender_api::{self, BorderRadius, BorderSide, BoxShadowClipMode, ClipMode, ColorF}; use webrender_api::{ComplexClipRegion, ExternalScrollId, FilterOp, GlyphInstance, ImageBorder}; -use webrender_api::{ImageRendering, LayoutRect, LayoutSize, LayoutVector2D, LineStyle, LocalClip}; -use webrender_api::{NinePatchDescriptor, NormalBorder, ScrollPolicy, ScrollSensitivity}; -use webrender_api::StickyOffsetBounds; +use webrender_api::{ImageRendering, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D}; +use webrender_api::{LineStyle, LocalClip, NinePatchDescriptor, NormalBorder, ScrollPolicy}; +use webrender_api::{ScrollSensitivity, StickyOffsetBounds}; trait ResolvePercentage { fn resolve(&self, length: u32) -> u32; @@ -2464,7 +2464,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { let perspective = self.fragment .perspective_matrix(&border_box) - .unwrap_or_else(Transform3D::identity); + .unwrap_or(LayoutTransform::identity()); let transform = transform.pre_mul(&perspective).inverse(); let origin = &border_box.origin; @@ -2766,10 +2766,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow { let content_size = self.base.overflow.scroll.origin + self.base.overflow.scroll.size; let content_size = Size2D::new(content_size.x, content_size.y); - let external_id = ExternalScrollId( - self.fragment.unique_id(), - state.pipeline_id.to_webrender() - ); + let external_id = + ExternalScrollId(self.fragment.unique_id(), state.pipeline_id.to_webrender()); let new_clip_scroll_index = state.add_clip_scroll_node(ClipScrollNode { parent_index: self.clipping_and_scrolling().scrolling, clip: clip, diff --git a/components/layout/display_list/webrender_helpers.rs b/components/layout/display_list/webrender_helpers.rs index 3c9a4b5dd3b..f657a628e45 100644 --- a/components/layout/display_list/webrender_helpers.rs +++ b/components/layout/display_list/webrender_helpers.rs @@ -11,8 +11,7 @@ use gfx::display_list::{BorderDetails, ClipScrollNode}; use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, DisplayItem}; use gfx::display_list::{DisplayList, StackingContextType}; use msg::constellation_msg::PipelineId; -use webrender_api::{self, ClipAndScrollInfo, ClipId}; -use webrender_api::{DisplayListBuilder, LayoutTransform}; +use webrender_api::{self, ClipAndScrollInfo, ClipId, DisplayListBuilder}; pub trait WebRenderDisplayListConverter { fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder; @@ -224,19 +223,12 @@ impl WebRenderDisplayItemConverter for DisplayItem { let stacking_context = &item.stacking_context; debug_assert_eq!(stacking_context.context_type, StackingContextType::Real); - let transform = stacking_context - .transform - .map(|transform| LayoutTransform::from_untyped(&transform).into()); - let perspective = stacking_context - .perspective - .map(|perspective| LayoutTransform::from_untyped(&perspective)); - builder.push_stacking_context( &webrender_api::LayoutPrimitiveInfo::new(stacking_context.bounds), stacking_context.scroll_policy, - transform, + stacking_context.transform.map(Into::into), stacking_context.transform_style, - perspective, + stacking_context.perspective, stacking_context.mix_blend_mode, stacking_context.filters.clone(), ); diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 399a21087c4..40a1b90972f 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -29,7 +29,7 @@ use app_units::Au; use block::{BlockFlow, FormattingContextType}; use context::LayoutContext; use display_list::{DisplayListBuildState, StackingContextCollectionState}; -use euclid::{Transform3D, Point2D, Vector2D, Rect, Size2D}; +use euclid::{Point2D, Vector2D, Rect, Size2D}; use flex::FlexFlow; use floats::{Floats, SpeculatedFloatPlacement}; use flow_list::{FlowList, FlowListIterator, MutFlowListIterator}; @@ -67,6 +67,7 @@ use table_colgroup::TableColGroupFlow; use table_row::TableRowFlow; use table_rowgroup::TableRowGroupFlow; use table_wrapper::TableWrapperFlow; +use webrender_api::LayoutTransform; /// This marker trait indicates that a type is a struct with `#[repr(C)]` whose first field /// is of type `BaseFlow` or some type that also implements this trait. @@ -335,8 +336,8 @@ pub trait Flow: HasBaseFlow + fmt::Debug + Sync + Send + 'static { let transform_2d = self.as_block() .fragment .transform_matrix(&position) - .unwrap_or(Transform3D::identity()) - .to_2d(); + .unwrap_or(LayoutTransform::identity()) + .to_2d().to_untyped(); let transformed_overflow = Overflow { paint: f32_rect_to_au_rect(transform_2d.transform_rect( &au_rect_to_f32_rect(overflow.paint))), diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 2ee3dbf0058..48764b625df 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -10,7 +10,8 @@ use ServoArc; use app_units::Au; use canvas_traits::canvas::CanvasMsg; use context::{LayoutContext, with_thread_local_font_context}; -use euclid::{Transform3D, Point2D, Vector2D, Rect, Size2D}; +use display_list::ToLayout; +use euclid::{Point2D, Vector2D, Rect, Size2D}; use floats::ClearType; use flow::{GetBaseFlow, ImmutableFlowUtils}; use flow_ref::FlowRef; @@ -65,7 +66,7 @@ use style::values::generics::box_::VerticalAlign; use style::values::generics::transform; use text; use text::TextRunScanner; -use webrender_api; +use webrender_api::{self, LayoutTransform}; use wrapper::ThreadSafeLayoutNodeHelpers; // From gfxFontConstants.h in Firefox. @@ -2867,9 +2868,10 @@ impl Fragment { } /// Returns the 4D matrix representing this fragment's transform. - pub fn transform_matrix(&self, stacking_relative_border_box: &Rect) -> Option> { + pub fn transform_matrix(&self, stacking_relative_border_box: &Rect) -> Option { let list = &self.style.get_box().transform; - let transform = list.to_transform_3d_matrix(Some(stacking_relative_border_box)).ok()?.0; + let transform = LayoutTransform::from_untyped( + &list.to_transform_3d_matrix(Some(stacking_relative_border_box)).ok()?.0); let transform_origin = &self.style.get_box().transform_origin; let transform_origin_x = @@ -2882,38 +2884,42 @@ impl Fragment { .to_f32_px(); let transform_origin_z = transform_origin.depth.px(); - let pre_transform = Transform3D::create_translation(transform_origin_x, - transform_origin_y, - transform_origin_z); - let post_transform = Transform3D::create_translation(-transform_origin_x, - -transform_origin_y, - -transform_origin_z); + let pre_transform = LayoutTransform::create_translation( + transform_origin_x, + transform_origin_y, + transform_origin_z); + let post_transform = LayoutTransform::create_translation( + -transform_origin_x, + -transform_origin_y, + -transform_origin_z); Some(pre_transform.pre_mul(&transform).pre_mul(&post_transform)) } /// Returns the 4D matrix representing this fragment's perspective. - pub fn perspective_matrix(&self, stacking_relative_border_box: &Rect) -> Option> { + pub fn perspective_matrix(&self, stacking_relative_border_box: &Rect) -> Option { match self.style().get_box().perspective { Either::First(length) => { let perspective_origin = self.style().get_box().perspective_origin; let perspective_origin = Point2D::new( perspective_origin.horizontal - .to_used_value(stacking_relative_border_box.size.width) - .to_f32_px(), + .to_used_value(stacking_relative_border_box.size.width), perspective_origin.vertical .to_used_value(stacking_relative_border_box.size.height) - .to_f32_px()); + ).to_layout(); - let pre_transform = Transform3D::create_translation(perspective_origin.x, - perspective_origin.y, - 0.0); - let post_transform = Transform3D::create_translation(-perspective_origin.x, - -perspective_origin.y, - 0.0); + let pre_transform = LayoutTransform::create_translation( + perspective_origin.x, + perspective_origin.y, + 0.0); + let post_transform = LayoutTransform::create_translation( + -perspective_origin.x, + -perspective_origin.y, + 0.0); - let perspective_matrix = transform::create_perspective_matrix(length.px()); + let perspective_matrix = LayoutTransform::from_untyped( + &transform::create_perspective_matrix(length.px())); Some(pre_transform.pre_mul(&perspective_matrix).pre_mul(&post_transform)) } diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 4270929c5e7..d9fca6c904f 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -17,6 +17,7 @@ use servo_config::opts; use style::servo::restyle_damage::ServoRestyleDamage; use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList}; use traversal::{InorderFlowTraversal, PostorderFlowTraversal, PreorderFlowTraversal}; +use webrender_api::LayoutPoint; pub fn resolve_generated_content(root: &mut Flow, layout_context: &LayoutContext) { ResolveGeneratedContent::new(&layout_context).traverse(root, 0); @@ -98,7 +99,7 @@ pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut Flow, iterator if let Some(matrix) = kid.as_block() .fragment .transform_matrix(&relative_position) { - let transform_matrix = matrix.transform_point2d(&Point2D::zero()); + let transform_matrix = matrix.transform_point2d(&LayoutPoint::zero()); stacking_context_position = stacking_context_position + Vector2D::new(Au::from_f32_px(transform_matrix.x), Au::from_f32_px(transform_matrix.y))