From 02e21a58db07275ef202dd743e4a39e445c61653 Mon Sep 17 00:00:00 2001 From: Morris Tseng Date: Thu, 24 Aug 2017 14:15:54 +0800 Subject: [PATCH 1/4] Add is_backface_visible information to display item and primitive. --- webrender/examples/animation.rs | 12 +- webrender/examples/basic.rs | 49 ++++-- webrender/examples/blob.rs | 25 ++- webrender/examples/iframe.rs | 20 ++- webrender/examples/image_resize.rs | 27 +++- webrender/examples/nested_display_list.rs | 66 +++++--- webrender/examples/scrolling.rs | 71 +++++++-- webrender/examples/texture_cache_stress.rs | 35 +++-- webrender/examples/yuv.rs | 25 ++- webrender/src/border.rs | 64 ++++---- webrender/src/frame.rs | 153 ++++++++++--------- webrender/src/frame_builder.rs | 167 ++++++++++----------- webrender/src/prim_store.rs | 13 ++ webrender/src/tiling.rs | 7 +- webrender_api/src/display_item.rs | 27 +++- webrender_api/src/display_list.rs | 126 +++++++++------- webrender_api/src/units.rs | 2 +- wrench/src/rawtest.rs | 26 +++- wrench/src/yaml_frame_reader.rs | 117 +++++++++------ wrench/src/yaml_frame_writer.rs | 1 + 20 files changed, 647 insertions(+), 386 deletions(-) diff --git a/webrender/examples/animation.rs b/webrender/examples/animation.rs index d1cf8514b5..df451a2726 100644 --- a/webrender/examples/animation.rs +++ b/webrender/examples/animation.rs @@ -31,8 +31,14 @@ impl Example for App { // Note the magic "42" we use as the animation key. That is used to update // the transform in the keyboard event handler code. let bounds = (0,0).to(100, 100); - builder.push_stacking_context(ScrollPolicy::Scrollable, - bounds, + let info = LayoutPrimitiveInfo { + rect: bounds, + local_clip: None, + is_backface_visible: true, + }; + + builder.push_stacking_context(&info, + ScrollPolicy::Scrollable, Some(PropertyBinding::Binding(PropertyBindingKey::new(42))), TransformStyle::Flat, None, @@ -40,7 +46,7 @@ impl Example for App { Vec::new()); // Fill it with a white rect - builder.push_rect(bounds, None, ColorF::new(1.0, 1.0, 1.0, 1.0)); + builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0)); builder.pop_stacking_context(); } diff --git a/webrender/examples/basic.rs b/webrender/examples/basic.rs index e19b62021b..beace7a5f1 100644 --- a/webrender/examples/basic.rs +++ b/webrender/examples/basic.rs @@ -185,8 +185,13 @@ impl Example for App { _pipeline_id: PipelineId, _document_id: DocumentId) { let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size); - builder.push_stacking_context(ScrollPolicy::Scrollable, - bounds, + let info = LayoutPrimitiveInfo { + rect: bounds, + local_clip: None, + is_backface_visible: true, + }; + builder.push_stacking_context(&info, + ScrollPolicy::Scrollable, None, TransformStyle::Flat, None, @@ -209,11 +214,19 @@ impl Example for App { let id = builder.define_clip(None, bounds, vec![complex], Some(mask)); builder.push_clip_id(id); - let bounds = (100, 100).to(200, 200); - builder.push_rect(bounds, None, ColorF::new(0.0, 1.0, 0.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (100, 100).to(200, 200), + local_clip: None, + is_backface_visible: true, + }; + builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); - let bounds = (250, 100).to(350, 200); - builder.push_rect(bounds, None, ColorF::new(0.0, 1.0, 0.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (250, 100).to(350, 200), + local_clip: None, + is_backface_visible: true, + }; + builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); let border_side = BorderSide { color: ColorF::new(0.0, 0.0, 1.0, 1.0), style: BorderStyle::Groove, @@ -232,8 +245,12 @@ impl Example for App { radius: BorderRadius::uniform(20.0), }); - let bounds = (100, 100).to(200, 200); - builder.push_border(bounds, None, border_widths, border_details); + let info = LayoutPrimitiveInfo { + rect: (100, 100).to(200, 200), + local_clip: None, + is_backface_visible: true, + }; + builder.push_border(&info, border_widths, border_details); if false { // draw text? @@ -295,9 +312,13 @@ impl Example for App { point: LayoutPoint::new(650.0, 100.0), }, ]; + let info = LayoutPrimitiveInfo { + rect: text_bounds, + local_clip: None, + is_backface_visible: true, + }; - builder.push_text(text_bounds, - None, + builder.push_text(&info, &glyphs, font_instance_key, ColorF::new(1.0, 1.0, 0.0, 1.0), @@ -313,9 +334,13 @@ impl Example for App { let spread_radius = 0.0; let simple_border_radius = 8.0; let box_shadow_type = BoxShadowClipMode::Inset; + let info = LayoutPrimitiveInfo { + rect: rect, + local_clip: Some(LocalClip::from(bounds)), + is_backface_visible: true, + }; - builder.push_box_shadow(rect, - Some(LocalClip::from(bounds)), + builder.push_box_shadow(&info, simple_box_bounds, offset, color, diff --git a/webrender/examples/blob.rs b/webrender/examples/blob.rs index ba2d64202f..3c02a6a67c 100644 --- a/webrender/examples/blob.rs +++ b/webrender/examples/blob.rs @@ -240,26 +240,39 @@ impl Example for App { ); let bounds = api::LayoutRect::new(api::LayoutPoint::zero(), layout_size); - builder.push_stacking_context(api::ScrollPolicy::Scrollable, - bounds, + let info = api::LayoutPrimitiveInfo { + rect: bounds, + local_clip: None, + is_backface_visible: true, + }; + builder.push_stacking_context(&info, + api::ScrollPolicy::Scrollable, None, api::TransformStyle::Flat, None, api::MixBlendMode::Normal, Vec::new()); + let info = api::LayoutPrimitiveInfo { + rect: (30, 30).by(500, 500), + local_clip: Some(api::LocalClip::from(bounds)), + is_backface_visible: true, + }; builder.push_image( - (30, 30).by(500, 500), - Some(api::LocalClip::from(bounds)), + &info, api::LayoutSize::new(500.0, 500.0), api::LayoutSize::new(0.0, 0.0), api::ImageRendering::Auto, blob_img1, ); + let info = api::LayoutPrimitiveInfo { + rect: (600, 600).by(200, 200), + local_clip: Some(api::LocalClip::from(bounds)), + is_backface_visible: true, + }; builder.push_image( - (600, 600).by(200, 200), - Some(api::LocalClip::from(bounds)), + &info, api::LayoutSize::new(200.0, 200.0), api::LayoutSize::new(0.0, 0.0), api::ImageRendering::Auto, diff --git a/webrender/examples/iframe.rs b/webrender/examples/iframe.rs index e661cf0794..eadcf0aec2 100644 --- a/webrender/examples/iframe.rs +++ b/webrender/examples/iframe.rs @@ -34,16 +34,21 @@ impl Example for App { let sub_pipeline_id = PipelineId(pipeline_id.0, 42); let mut sub_builder = DisplayListBuilder::new(sub_pipeline_id, sub_bounds.size); + let info = LayoutPrimitiveInfo { + rect: sub_bounds, + local_clip: None, + is_backface_visible: true, + }; - sub_builder.push_stacking_context(ScrollPolicy::Scrollable, - sub_bounds, + sub_builder.push_stacking_context(&info, + ScrollPolicy::Scrollable, None, TransformStyle::Flat, None, MixBlendMode::Normal, Vec::new()); // green rect visible == success - sub_builder.push_rect(sub_bounds, None, ColorF::new(0.0, 1.0, 0.0, 1.0)); + sub_builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); sub_builder.pop_stacking_context(); api.set_display_list( @@ -56,18 +61,17 @@ impl Example for App { ResourceUpdates::new(), ); - let bounds = sub_bounds; // And this is for the root pipeline - builder.push_stacking_context(ScrollPolicy::Scrollable, - bounds, + builder.push_stacking_context(&info, + ScrollPolicy::Scrollable, Some(PropertyBinding::Binding(PropertyBindingKey::new(42))), TransformStyle::Flat, None, MixBlendMode::Normal, Vec::new()); // red rect under the iframe: if this is visible, things have gone wrong - builder.push_rect(bounds, None, ColorF::new(1.0, 0.0, 0.0, 1.0)); - builder.push_iframe(bounds, None, sub_pipeline_id); + builder.push_rect(&info, ColorF::new(1.0, 0.0, 0.0, 1.0)); + builder.push_iframe(&info, sub_pipeline_id); builder.pop_stacking_context(); } diff --git a/webrender/examples/image_resize.rs b/webrender/examples/image_resize.rs index dea82bf685..0a02ca58b9 100644 --- a/webrender/examples/image_resize.rs +++ b/webrender/examples/image_resize.rs @@ -39,9 +39,14 @@ impl Example for App { None, ); - let bounds = (0,0).to(512, 512); - builder.push_stacking_context(ScrollPolicy::Scrollable, - bounds, + let bounds = (0, 0).to(512, 512); + let info = LayoutPrimitiveInfo { + rect: bounds, + local_clip: None, + is_backface_visible: true, + }; + builder.push_stacking_context(&info, + ScrollPolicy::Scrollable, None, TransformStyle::Flat, None, @@ -50,18 +55,26 @@ impl Example for App { let image_size = LayoutSize::new(100.0, 100.0); + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size), + local_clip: Some(LocalClip::from(bounds)), + is_backface_visible: true, + }; builder.push_image( - LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size), - Some(LocalClip::from(bounds)), + &info, image_size, LayoutSize::zero(), ImageRendering::Auto, self.image_key ); + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(250.0, 100.0), image_size), + local_clip: Some(LocalClip::from(bounds)), + is_backface_visible: true, + }; builder.push_image( - LayoutRect::new(LayoutPoint::new(250.0, 100.0), image_size), - Some(LocalClip::from(bounds)), + &info, image_size, LayoutSize::zero(), ImageRendering::Pixelated, diff --git a/webrender/examples/nested_display_list.rs b/webrender/examples/nested_display_list.rs index 223ef24cc0..a9b904c432 100644 --- a/webrender/examples/nested_display_list.rs +++ b/webrender/examples/nested_display_list.rs @@ -25,8 +25,13 @@ impl Example for App { pipeline_id: PipelineId, _document_id: DocumentId) { let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size); - builder.push_stacking_context(ScrollPolicy::Scrollable, - bounds, + let info = LayoutPrimitiveInfo { + rect: bounds, + local_clip: None, + is_backface_visible: true, + }; + builder.push_stacking_context(&info, + ScrollPolicy::Scrollable, None, TransformStyle::Flat, None, @@ -34,7 +39,12 @@ impl Example for App { Vec::new()); let outer_scroll_frame_rect = (100, 100).to(600, 400); - builder.push_rect(outer_scroll_frame_rect, None, ColorF::new(1.0, 1.0, 1.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: outer_scroll_frame_rect, + local_clip: None, + is_backface_visible: true, + }; + builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0)); let nested_clip_id = builder.define_scroll_frame(None, (100, 100).to(1000, 1000), @@ -47,27 +57,45 @@ impl Example for App { let mut builder2 = DisplayListBuilder::new(pipeline_id, layout_size); let mut builder3 = DisplayListBuilder::new(pipeline_id, layout_size); - let rect = (110, 110).to(210, 210); - builder3.push_rect(rect, None, ColorF::new(0.0, 1.0, 0.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (110, 110).to(210, 210), + local_clip: None, + is_backface_visible: true, + }; + builder3.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); // A fixed position rectangle should be fixed to the reference frame that starts // in the outer display list. - builder3.push_stacking_context(ScrollPolicy::Fixed, - (220, 110).to(320, 210), - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new()); - let rect = (0, 0).to(100, 100); - builder3.push_rect(rect, None, ColorF::new(0.0, 1.0, 0.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (220, 110).to(320, 210), + local_clip: None, + is_backface_visible: true, + }; + builder3.push_stacking_context(&info, + ScrollPolicy::Fixed, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new()); + let info = LayoutPrimitiveInfo { + rect: (0, 0).to(100, 100), + local_clip: None, + is_backface_visible: true, + }; + builder3.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); builder3.pop_stacking_context(); // Now we push an inner scroll frame that should have the same id as the outer one, // but the WebRender nested display list replacement code should convert it into // a unique ClipId. let inner_scroll_frame_rect = (330, 110).to(530, 360); - builder3.push_rect(inner_scroll_frame_rect, None, ColorF::new(1.0, 0.0, 1.0, 0.5)); + let info = LayoutPrimitiveInfo { + rect: inner_scroll_frame_rect, + local_clip: None, + is_backface_visible: true, + }; + builder3.push_rect(&info, ColorF::new(1.0, 0.0, 1.0, 0.5)); let inner_nested_clip_id = builder3.define_scroll_frame(None, (330, 110).to(2000, 2000), @@ -76,8 +104,12 @@ impl Example for App { None, ScrollSensitivity::ScriptAndInputEvents); builder3.push_clip_id(inner_nested_clip_id); - let rect = (340, 120).to(440, 220); - builder3.push_rect(rect, None, ColorF::new(0.0, 1.0, 0.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (340, 120).to(440, 220), + local_clip: None, + is_backface_visible: true, + }; + builder3.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); builder3.pop_clip_id(); let (_, _, built_list) = builder3.finalize(); diff --git a/webrender/examples/scrolling.rs b/webrender/examples/scrolling.rs index 2d48390e94..4b662d5b88 100644 --- a/webrender/examples/scrolling.rs +++ b/webrender/examples/scrolling.rs @@ -24,9 +24,13 @@ impl Example for App { layout_size: LayoutSize, _pipeline_id: PipelineId, _document_id: DocumentId) { - let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size); - builder.push_stacking_context(ScrollPolicy::Scrollable, - bounds, + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::zero(), layout_size), + local_clip: None, + is_backface_visible: true, + }; + builder.push_stacking_context(&info, + ScrollPolicy::Scrollable, None, TransformStyle::Flat, None, @@ -36,9 +40,14 @@ impl Example for App { if true { // scrolling and clips stuff // let's make a scrollbox let scrollbox = (0, 0).to(300, 400); - builder.push_stacking_context(ScrollPolicy::Scrollable, - LayoutRect::new(LayoutPoint::new(10.0, 10.0), - LayoutSize::zero()), + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(10.0, 10.0), + LayoutSize::zero()), + local_clip: None, + is_backface_visible: true, + }; + builder.push_stacking_context(&info, + ScrollPolicy::Scrollable, None, TransformStyle::Flat, None, @@ -55,15 +64,29 @@ impl Example for App { // now put some content into it. // start with a white background - builder.push_rect((0, 0).to(1000, 1000), None, ColorF::new(1.0, 1.0, 1.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (0, 0).to(1000, 1000), + local_clip: None, + is_backface_visible: true, + }; + builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0)); // let's make a 50x50 blue square as a visual reference - builder.push_rect((0, 0).to(50, 50), None, ColorF::new(0.0, 0.0, 1.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (0, 0).to(50, 50), + local_clip: None, + is_backface_visible: true, + }; + builder.push_rect(&info, ColorF::new(0.0, 0.0, 1.0, 1.0)); // and a 50x50 green square next to it with an offset clip // to see what that looks like - builder.push_rect((50, 0).to(100, 50), - Some(LocalClip::from((60, 10).to(110, 60))), + let info = LayoutPrimitiveInfo { + rect: (50, 0).to(100, 50), + local_clip: Some(LocalClip::from((60, 10).to(110, 60))), + is_backface_visible: true, + }; + builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); // Below the above rectangles, set up a nested scrollbox. It's still in @@ -79,11 +102,21 @@ impl Example for App { // give it a giant gray background just to distinguish it and to easily // visually identify the nested scrollbox - builder.push_rect((-1000, -1000).to(5000, 5000), None, ColorF::new(0.5, 0.5, 0.5, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (-1000, -1000).to(5000, 5000), + local_clip: None, + is_backface_visible: true, + }; + builder.push_rect(&info, ColorF::new(0.5, 0.5, 0.5, 1.0)); // add a teal square to visualize the scrolling/clipping behaviour // as you scroll the nested scrollbox - builder.push_rect((0, 200).to(50, 250), None, ColorF::new(0.0, 1.0, 1.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (0, 200).to(50, 250), + local_clip: None, + is_backface_visible: true, + }; + builder.push_rect(&info, ColorF::new(0.0, 1.0, 1.0, 1.0)); // Add a sticky frame. It will "stick" at a margin of 10px from the top, until // the scrollframe scrolls another 60px, at which point it will "unstick". This lines @@ -95,13 +128,23 @@ impl Example for App { StickyFrameInfo::new(Some(StickySideConstraint{ margin: 10.0, max_offset: 60.0 }), None, None, None)); builder.push_clip_id(sticky_id); - builder.push_rect((50, 140).to(100, 190), None, ColorF::new(0.5, 0.5, 1.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (50, 140).to(100, 190), + local_clip: None, + is_backface_visible: true, + }; + builder.push_rect(&info, ColorF::new(0.5, 0.5, 1.0, 1.0)); builder.pop_clip_id(); // sticky_id // just for good measure add another teal square in the bottom-right // corner of the nested scrollframe content, which can be scrolled into // view by the user - builder.push_rect((250, 350).to(300, 400), None, ColorF::new(0.0, 1.0, 1.0, 1.0)); + let info = LayoutPrimitiveInfo { + rect: (250, 350).to(300, 400), + local_clip: None, + is_backface_visible: true, + }; + builder.push_rect(&info, ColorF::new(0.0, 1.0, 1.0, 1.0)); builder.pop_clip_id(); // nested_clip_id diff --git a/webrender/examples/texture_cache_stress.rs b/webrender/examples/texture_cache_stress.rs index 7190891a92..27b2f00eb4 100644 --- a/webrender/examples/texture_cache_stress.rs +++ b/webrender/examples/texture_cache_stress.rs @@ -87,9 +87,14 @@ impl Example for App { _layout_size: LayoutSize, _pipeline_id: PipelineId, _document_id: DocumentId) { - let bounds = (0,0).to(512, 512); - builder.push_stacking_context(ScrollPolicy::Scrollable, - bounds, + let bounds = (0, 0).to(512, 512); + let info = LayoutPrimitiveInfo { + rect: bounds, + local_clip: None, + is_backface_visible: true, + }; + builder.push_stacking_context(&info, + ScrollPolicy::Scrollable, None, TransformStyle::Flat, None, @@ -127,10 +132,14 @@ impl Example for App { for (i, key) in self.stress_keys.iter().enumerate() { let x = (i % 128) as f32; let y = (i / 128) as f32; + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(x0 + image_size.width * x, y0 + image_size.height * y), image_size), + local_clip: Some(LocalClip::from(bounds)), + is_backface_visible: true, + }; builder.push_image( - LayoutRect::new(LayoutPoint::new(x0 + image_size.width * x, y0 + image_size.height * y), image_size), - Some(LocalClip::from(bounds)), + &info, image_size, LayoutSize::zero(), ImageRendering::Auto, @@ -140,10 +149,14 @@ impl Example for App { if let Some(image_key) = self.image_key { let image_size = LayoutSize::new(100.0, 100.0); + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size), + local_clip: Some(LocalClip::from(bounds)), + is_backface_visible: true, + }; builder.push_image( - LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size), - Some(LocalClip::from(bounds)), + &info, image_size, LayoutSize::zero(), ImageRendering::Auto, @@ -153,10 +166,14 @@ impl Example for App { let swap_key = self.swap_keys[self.swap_index]; let image_size = LayoutSize::new(64.0, 64.0); + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(100.0, 400.0), image_size), + local_clip: Some(LocalClip::from(bounds)), + is_backface_visible: true, + }; builder.push_image( - LayoutRect::new(LayoutPoint::new(100.0, 400.0), image_size), - Some(LocalClip::from(bounds)), + &info, image_size, LayoutSize::zero(), ImageRendering::Auto, diff --git a/webrender/examples/yuv.rs b/webrender/examples/yuv.rs index 9cd4b9ccb8..8074a34c54 100644 --- a/webrender/examples/yuv.rs +++ b/webrender/examples/yuv.rs @@ -165,8 +165,13 @@ impl Example for App { _pipeline_id: PipelineId, _document_id: DocumentId) { let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size); - builder.push_stacking_context(ScrollPolicy::Scrollable, - bounds, + let info = LayoutPrimitiveInfo { + rect: bounds, + local_clip: None, + is_backface_visible: true, + }; + builder.push_stacking_context(&info, + ScrollPolicy::Scrollable, None, TransformStyle::Flat, None, @@ -202,17 +207,25 @@ impl Example for App { None, ); + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(100.0, 0.0), LayoutSize::new(100.0, 100.0)), + local_clip: Some(LocalClip::from(bounds)), + is_backface_visible: true, + }; builder.push_yuv_image( - LayoutRect::new(LayoutPoint::new(100.0, 0.0), LayoutSize::new(100.0, 100.0)), - Some(LocalClip::from(bounds)), + &info, YuvData::NV12(yuv_chanel1, yuv_chanel2), YuvColorSpace::Rec601, ImageRendering::Auto, ); + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(300.0, 0.0), LayoutSize::new(100.0, 100.0)), + local_clip: Some(LocalClip::from(bounds)), + is_backface_visible: true, + }; builder.push_yuv_image( - LayoutRect::new(LayoutPoint::new(300.0, 0.0), LayoutSize::new(100.0, 100.0)), - Some(LocalClip::from(bounds)), + &info, YuvData::PlanarYCbCr(yuv_chanel1, yuv_chanel2_1, yuv_chanel3), YuvColorSpace::Rec601, ImageRendering::Auto, diff --git a/webrender/src/border.rs b/webrender/src/border.rs index 49e798018a..cec2a51a65 100644 --- a/webrender/src/border.rs +++ b/webrender/src/border.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use api::{BorderSide, BorderStyle, BorderWidths, ClipAndScrollInfo, ColorF, LayerPoint, LayerRect}; -use api::{LayerSize, LocalClip, NormalBorder}; +use api::{LayerPrimitiveInfo, LayerSize, NormalBorder}; use clip::ClipSource; use ellipse::Ellipse; use gpu_cache::GpuDataRequest; @@ -222,11 +222,10 @@ impl NormalBorderHelpers for NormalBorder { impl FrameBuilder { fn add_normal_border_primitive(&mut self, - rect: &LayerRect, + info: &LayerPrimitiveInfo, border: &NormalBorder, widths: &BorderWidths, clip_and_scroll: ClipAndScrollInfo, - local_clip: &LocalClip, corner_instances: [BorderCornerInstance; 4], clip_sources: Vec) { let radius = &border.radius; @@ -272,8 +271,7 @@ impl FrameBuilder { }; self.add_primitive(clip_and_scroll, - &rect, - local_clip, + info, clip_sources, PrimitiveContainer::Border(prim_cpu)); } @@ -283,11 +281,10 @@ impl FrameBuilder { // are converted, this can be removed, along with the complex // border code path. pub fn add_normal_border(&mut self, - rect: &LayerRect, + info: &LayerPrimitiveInfo, border: &NormalBorder, widths: &BorderWidths, - clip_and_scroll: ClipAndScrollInfo, - local_clip: &LocalClip) { + clip_and_scroll: ClipAndScrollInfo) { // The border shader is quite expensive. For simple borders, we can just draw // the border with a few rectangles. This generally gives better batching, and // a GPU win in fragment shader time. @@ -310,28 +307,28 @@ impl FrameBuilder { widths.top, &radius.top_left, BorderCorner::TopLeft, - rect), + &info.rect), border.get_corner(right, widths.right, top, widths.top, &radius.top_right, BorderCorner::TopRight, - rect), + &info.rect), border.get_corner(right, widths.right, bottom, widths.bottom, &radius.bottom_right, BorderCorner::BottomRight, - rect), + &info.rect), border.get_corner(left, widths.left, bottom, widths.bottom, &radius.bottom_left, BorderCorner::BottomLeft, - rect), + &info.rect), ]; let (left_edge, left_len) = border.get_edge(left, widths.left); @@ -358,43 +355,47 @@ impl FrameBuilder { let has_no_curve = radius.is_zero(); if has_no_curve && all_corners_simple && all_edges_simple { - let p0 = rect.origin; - let p1 = rect.bottom_right(); - let rect_width = rect.size.width; - let rect_height = rect.size.height; + let p0 = info.rect.origin; + let p1 = info.rect.bottom_right(); + let rect_width = info.rect.size.width; + let rect_height = info.rect.size.height; // Add a solid rectangle for each visible edge/corner combination. if top_edge == BorderEdgeKind::Solid { + let mut info = info.clone(); + info.rect = LayerRect::new(p0, LayerSize::new(rect_width, top_len)); self.add_solid_rectangle(clip_and_scroll, - &LayerRect::new(p0, LayerSize::new(rect_width, top_len)), - local_clip, + &info, &border.top.color, PrimitiveFlags::None); } if left_edge == BorderEdgeKind::Solid { + let mut info = info.clone(); + info.rect = LayerRect::new(LayerPoint::new(p0.x, p0.y + top_len), + LayerSize::new(left_len, + rect_height - top_len - bottom_len)); self.add_solid_rectangle(clip_and_scroll, - &LayerRect::new(LayerPoint::new(p0.x, p0.y + top_len), - LayerSize::new(left_len, - rect_height - top_len - bottom_len)), - local_clip, + &info, &border.left.color, PrimitiveFlags::None); } if right_edge == BorderEdgeKind::Solid { + let mut info = info.clone(); + info.rect = LayerRect::new(LayerPoint::new(p1.x - right_len, + p0.y + top_len), + LayerSize::new(right_len, + rect_height - top_len - bottom_len)); self.add_solid_rectangle(clip_and_scroll, - &LayerRect::new(LayerPoint::new(p1.x - right_len, - p0.y + top_len), - LayerSize::new(right_len, - rect_height - top_len - bottom_len)), - local_clip, + &info, &border.right.color, PrimitiveFlags::None); } if bottom_edge == BorderEdgeKind::Solid { + let mut info = info.clone(); + info.rect = LayerRect::new(LayerPoint::new(p0.x, p1.y - bottom_len), + LayerSize::new(rect_width, bottom_len)); self.add_solid_rectangle(clip_and_scroll, - &LayerRect::new(LayerPoint::new(p0.x, p1.y - bottom_len), - LayerSize::new(rect_width, bottom_len)), - local_clip, + &info, &border.bottom.color, PrimitiveFlags::None); } @@ -419,11 +420,10 @@ impl FrameBuilder { } } - self.add_normal_border_primitive(rect, + self.add_normal_border_primitive(info, border, widths, clip_and_scroll, - local_clip, corner_instances, extra_clips); } diff --git a/webrender/src/frame.rs b/webrender/src/frame.rs index 586d3da9bc..287e0cd06f 100644 --- a/webrender/src/frame.rs +++ b/webrender/src/frame.rs @@ -4,7 +4,7 @@ use api::{BuiltDisplayList, BuiltDisplayListIter, ClipAndScrollInfo, ClipId, ColorF}; use api::{ComplexClipRegion, DeviceUintRect, DeviceUintSize, DisplayItemRef, Epoch, FilterOp}; -use api::{ImageDisplayItem, ItemRange, LayerPoint, LayerRect, LayerSize, LayerToScrollTransform}; +use api::{ImageDisplayItem, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize, LayerToScrollTransform}; use api::{LayerVector2D, LayoutSize, LayoutTransform, LocalClip, MixBlendMode, PipelineId}; use api::{PropertyBinding, ScrollClamping, ScrollEventPhase, ScrollLayerState, ScrollLocation}; use api::{ScrollPolicy, ScrollSensitivity, SpecificDisplayItem, StackingContext, TileOffset}; @@ -420,7 +420,8 @@ impl Frame { mut reference_frame_relative_offset: LayerVector2D, bounds: &LayerRect, stacking_context: &StackingContext, - filters: ItemRange) { + filters: ItemRange, + is_backface_visible: bool) { // Avoid doing unnecessary work for empty stacking contexts. if traversal.current_stacking_context_empty() { traversal.skip_current_stacking_context(); @@ -476,7 +477,8 @@ impl Frame { context.builder.push_stacking_context(&reference_frame_relative_offset, pipeline_id, composition_operations, - stacking_context.transform_style); + stacking_context.transform_style, + is_backface_visible); self.flatten_items(traversal, pipeline_id, @@ -562,9 +564,7 @@ impl Frame { clip_and_scroll.scroll_node_id = context.apply_scroll_frame_id_replacement(clip_and_scroll.scroll_node_id); - - let item_rect_with_offset = item.rect().translate(&reference_frame_relative_offset); - let clip_with_offset = item.local_clip_with_offset(&reference_frame_relative_offset); + let prim_info = item.get_layer_primitive_info(&reference_frame_relative_offset); match *item.item() { SpecificDisplayItem::Image(ref info) => { if let Some(tiling) = context.tiled_image_map.get(&info.image_key) { @@ -572,15 +572,13 @@ impl Frame { // for each tile. self.decompose_image(clip_and_scroll, &mut context.builder, - &item_rect_with_offset, - &clip_with_offset, + &prim_info, info, tiling.image_size, tiling.tile_size as u32); } else { context.builder.add_image(clip_and_scroll, - item_rect_with_offset, - &clip_with_offset, + &prim_info, &info.stretch_size, &info.tile_spacing, None, @@ -591,8 +589,7 @@ impl Frame { } SpecificDisplayItem::YuvImage(ref info) => { context.builder.add_yuv_image(clip_and_scroll, - item_rect_with_offset, - &clip_with_offset, + &prim_info, info.yuv_data, info.color_space, info.image_rendering); @@ -602,8 +599,7 @@ impl Frame { Some(instance) => { context.builder.add_text(clip_and_scroll, reference_frame_relative_offset, - item_rect_with_offset, - &clip_with_offset, + &prim_info, instance, &text_info.color, item.glyphs(), @@ -617,21 +613,25 @@ impl Frame { } SpecificDisplayItem::Rectangle(ref info) => { if !self.try_to_add_rectangle_splitting_on_clip(context, - &item_rect_with_offset, - &clip_with_offset, + &prim_info, &info.color, &clip_and_scroll) { context.builder.add_solid_rectangle(clip_and_scroll, - &item_rect_with_offset, - &clip_with_offset, + &prim_info, &info.color, PrimitiveFlags::None); } } SpecificDisplayItem::Line(ref info) => { + let prim_info = LayerPrimitiveInfo { + rect: LayerRect::zero(), + local_clip: Some(*item.local_clip()), + is_backface_visible: prim_info.is_backface_visible, + }; + context.builder.add_line(clip_and_scroll, - item.local_clip(), + &prim_info, info.baseline, info.start, info.end, @@ -642,8 +642,7 @@ impl Frame { } SpecificDisplayItem::Gradient(ref info) => { context.builder.add_gradient(clip_and_scroll, - item_rect_with_offset, - &clip_with_offset, + &prim_info, info.gradient.start_point, info.gradient.end_point, item.gradient_stops(), @@ -655,8 +654,7 @@ impl Frame { } SpecificDisplayItem::RadialGradient(ref info) => { context.builder.add_radial_gradient(clip_and_scroll, - item_rect_with_offset, - &clip_with_offset, + &prim_info, info.gradient.start_center, info.gradient.start_radius, info.gradient.end_center, @@ -669,9 +667,10 @@ impl Frame { } SpecificDisplayItem::BoxShadow(ref box_shadow_info) => { let bounds = box_shadow_info.box_bounds.translate(&reference_frame_relative_offset); + let mut prim_info = prim_info.clone(); + prim_info.rect = bounds; context.builder.add_box_shadow(clip_and_scroll, - &bounds, - &clip_with_offset, + &prim_info, &box_shadow_info.offset, &box_shadow_info.color, box_shadow_info.blur_radius, @@ -681,8 +680,7 @@ impl Frame { } SpecificDisplayItem::Border(ref info) => { context.builder.add_border(clip_and_scroll, - item_rect_with_offset, - &clip_with_offset, + &prim_info, info, item.gradient_stops(), item.display_list() @@ -697,7 +695,8 @@ impl Frame { reference_frame_relative_offset, &item.rect(), &info.stacking_context, - item.filters()); + item.filters(), + prim_info.is_backface_visible); return Some(subtraversal); } SpecificDisplayItem::Iframe(ref info) => { @@ -772,9 +771,11 @@ impl Frame { SpecificDisplayItem::PopStackingContext => unreachable!("Should have returned in parent method."), SpecificDisplayItem::PushTextShadow(shadow) => { + let mut prim_info = prim_info.clone(); + prim_info.rect = LayerRect::zero(); context.builder.push_text_shadow(shadow, clip_and_scroll, - &clip_with_offset); + &prim_info); } SpecificDisplayItem::PopTextShadow => { context.builder.pop_text_shadow(); @@ -789,8 +790,7 @@ impl Frame { /// potential for further optimizations. fn try_to_add_rectangle_splitting_on_clip(&mut self, context: &mut FlattenContext, - rect: &LayerRect, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, color: &ColorF, clip_and_scroll: &ClipAndScrollInfo) -> bool { @@ -801,7 +801,8 @@ impl Frame { return false; } - let inner_unclipped_rect = match local_clip { + let local_clip = info.local_clip.unwrap(); + let inner_unclipped_rect = match &local_clip { &LocalClip::Rect(_) => return false, &LocalClip::RoundedRect(_, ref region) => region.get_inner_rect_full(), }; @@ -814,18 +815,24 @@ impl Frame { // let it be clipped by the parent of the clipping node, which may result in // less masking some cases. let mut clipped_rects = Vec::new(); - subtract_rect(rect, &inner_unclipped_rect, &mut clipped_rects); + subtract_rect(&info.rect, &inner_unclipped_rect, &mut clipped_rects); + + let prim_info = LayerPrimitiveInfo { + rect: inner_unclipped_rect, + local_clip: Some(LocalClip::from(*info.local_clip.unwrap().clip_rect())), + is_backface_visible: info.is_backface_visible, + }; context.builder.add_solid_rectangle(*clip_and_scroll, - &inner_unclipped_rect, - &LocalClip::from(*local_clip.clip_rect()), + &prim_info, color, PrimitiveFlags::None); for clipped_rect in &clipped_rects { + let mut info = info.clone(); + info.rect = *clipped_rect; context.builder.add_solid_rectangle(*clip_and_scroll, - clipped_rect, - local_clip, + &info, color, PrimitiveFlags::None); } @@ -840,7 +847,8 @@ impl Frame { context.builder.push_stacking_context(&LayerVector2D::zero(), pipeline_id, CompositeOps::default(), - TransformStyle::Flat); + TransformStyle::Flat, + true); // We do this here, rather than above because we want any of the top-level // stacking contexts in the display list to be treated like root stacking contexts. @@ -855,9 +863,9 @@ impl Frame { if let Some(pipeline) = context.scene.pipeline_map.get(&pipeline_id) { if let Some(bg_color) = pipeline.background_color { let root_bounds = LayerRect::new(LayerPoint::zero(), *content_size); + let info = LayerPrimitiveInfo::new(root_bounds); context.builder.add_solid_rectangle(ClipAndScrollInfo::simple(clip_id), - &root_bounds, - &LocalClip::from(root_bounds), + &info, &bg_color, PrimitiveFlags::None); } @@ -869,10 +877,11 @@ impl Frame { if self.frame_builder_config.enable_scrollbars { let scrollbar_rect = LayerRect::new(LayerPoint::zero(), LayerSize::new(10.0, 70.0)); + let info = LayerPrimitiveInfo::new(scrollbar_rect); + context.builder.add_solid_rectangle( ClipAndScrollInfo::simple(clip_id), - &scrollbar_rect, - &LocalClip::from(scrollbar_rect), + &info, &DEFAULT_SCROLLBAR_COLOR, PrimitiveFlags::Scrollbar(self.clip_scroll_tree.topmost_scrolling_node_id(), 4.0)); } @@ -921,18 +930,17 @@ impl Frame { fn decompose_image(&mut self, clip_and_scroll: ClipAndScrollInfo, builder: &mut FrameBuilder, - item_rect: &LayerRect, - item_local_clip: &LocalClip, + prim_info: &LayerPrimitiveInfo, info: &ImageDisplayItem, image_size: DeviceUintSize, tile_size: u32) { let no_vertical_tiling = image_size.height <= tile_size; let no_vertical_spacing = info.tile_spacing.height == 0.0; + let item_rect = prim_info.rect; if no_vertical_tiling && no_vertical_spacing { self.decompose_image_row(clip_and_scroll, builder, - item_rect, - item_local_clip, + prim_info, info, image_size, tile_size); @@ -948,11 +956,12 @@ impl Frame { item_rect.origin.y + (i as f32) * layout_stride, item_rect.size.width, info.stretch_size.height - ).intersection(item_rect) { + ).intersection(&item_rect) { + let mut prim_info = prim_info.clone(); + prim_info.rect = row_rect; self.decompose_image_row(clip_and_scroll, builder, - &row_rect, - item_local_clip, + &prim_info, info, image_size, tile_size); @@ -963,8 +972,7 @@ impl Frame { fn decompose_image_row(&mut self, clip_and_scroll: ClipAndScrollInfo, builder: &mut FrameBuilder, - item_rect: &LayerRect, - item_local_clip: &LocalClip, + prim_info: &LayerPrimitiveInfo, info: &ImageDisplayItem, image_size: DeviceUintSize, tile_size: u32) { @@ -973,8 +981,7 @@ impl Frame { if no_horizontal_tiling && no_horizontal_spacing { self.decompose_tiled_image(clip_and_scroll, builder, - item_rect, - item_local_clip, + prim_info, info, image_size, tile_size); @@ -982,6 +989,7 @@ impl Frame { } // Decompose each horizontal repetition. + let item_rect = prim_info.rect; let layout_stride = info.stretch_size.width + info.tile_spacing.width; let num_repetitions = (item_rect.size.width / layout_stride).ceil() as u32; for i in 0..num_repetitions { @@ -990,11 +998,12 @@ impl Frame { item_rect.origin.y, info.stretch_size.width, item_rect.size.height, - ).intersection(item_rect) { + ).intersection(&item_rect) { + let mut prim_info = prim_info.clone(); + prim_info.rect = decomposed_rect; self.decompose_tiled_image(clip_and_scroll, builder, - &decomposed_rect, - item_local_clip, + &prim_info, info, image_size, tile_size); @@ -1005,8 +1014,7 @@ impl Frame { fn decompose_tiled_image(&mut self, clip_and_scroll: ClipAndScrollInfo, builder: &mut FrameBuilder, - item_rect: &LayerRect, - item_local_clip: &LocalClip, + prim_info: &LayerPrimitiveInfo, info: &ImageDisplayItem, image_size: DeviceUintSize, tile_size: u32) { @@ -1041,6 +1049,7 @@ impl Frame { // This can happen with very tall and thin images used as a repeating background. // Apparently web authors do that... + let item_rect = prim_info.rect; let needs_repeat_x = info.stretch_size.width < item_rect.size.width; let needs_repeat_y = info.stretch_size.height < item_rect.size.height; @@ -1077,8 +1086,7 @@ impl Frame { for tx in 0..num_tiles_x { self.add_tile_primitive(clip_and_scroll, builder, - item_rect, - item_local_clip, + prim_info, info, TileOffset::new(tx, ty), stretched_tile_size, @@ -1089,8 +1097,7 @@ impl Frame { // Tiles on the right edge that are smaller than the tile size. self.add_tile_primitive(clip_and_scroll, builder, - item_rect, - item_local_clip, + prim_info, info, TileOffset::new(num_tiles_x, ty), stretched_tile_size, @@ -1105,8 +1112,7 @@ impl Frame { // Tiles on the bottom edge that are smaller than the tile size. self.add_tile_primitive(clip_and_scroll, builder, - item_rect, - item_local_clip, + prim_info, info, TileOffset::new(tx, num_tiles_y), stretched_tile_size, @@ -1120,8 +1126,7 @@ impl Frame { // Finally, the bottom-right tile with a "leftover" size. self.add_tile_primitive(clip_and_scroll, builder, - item_rect, - item_local_clip, + prim_info, info, TileOffset::new(num_tiles_x, num_tiles_y), stretched_tile_size, @@ -1136,8 +1141,7 @@ impl Frame { fn add_tile_primitive(&mut self, clip_and_scroll: ClipAndScrollInfo, builder: &mut FrameBuilder, - item_rect: &LayerRect, - item_local_clip: &LocalClip, + prim_info: &LayerPrimitiveInfo, info: &ImageDisplayItem, tile_offset: TileOffset, stretched_tile_size: LayerSize, @@ -1160,7 +1164,7 @@ impl Frame { ); let mut prim_rect = LayerRect::new( - item_rect.origin + LayerVector2D::new( + prim_info.rect.origin + LayerVector2D::new( tile_offset.x as f32 * stretched_tile_size.width, tile_offset.y as f32 * stretched_tile_size.height, ), @@ -1169,19 +1173,20 @@ impl Frame { if shader_repeat_x { assert_eq!(tile_offset.x, 0); - prim_rect.size.width = item_rect.size.width; + prim_rect.size.width = prim_info.rect.size.width; } if shader_repeat_y { assert_eq!(tile_offset.y, 0); - prim_rect.size.height = item_rect.size.height; + prim_rect.size.height = prim_info.rect.size.height; } // Fix up the primitive's rect if it overflows the original item rect. - if let Some(prim_rect) = prim_rect.intersection(item_rect) { + if let Some(prim_rect) = prim_rect.intersection(&prim_info.rect) { + let mut prim_info = prim_info.clone(); + prim_info.rect = prim_rect; builder.add_image(clip_and_scroll, - prim_rect, - item_local_clip, + &prim_info, &stretched_size, &info.tile_spacing, None, diff --git a/webrender/src/frame_builder.rs b/webrender/src/frame_builder.rs index 2e70a72a51..1a42dbc2e6 100644 --- a/webrender/src/frame_builder.rs +++ b/webrender/src/frame_builder.rs @@ -6,7 +6,7 @@ use api::{BorderDetails, BorderDisplayItem, BorderRadius, BoxShadowClipMode, Cli use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceUintRect, DeviceUintSize}; use api::{ExtendMode, FontInstance, FontRenderMode}; use api::{GlyphInstance, GlyphOptions, GradientStop}; -use api::{ImageKey, ImageRendering, ItemRange, LayerPoint, LayerRect, LayerSize}; +use api::{ImageKey, ImageRendering, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize}; use api::{LayerToScrollTransform, LayerVector2D, LayoutVector2D, LineOrientation, LineStyle}; use api::{LocalClip, PipelineId, RepeatMode, ScrollSensitivity, SubpixelDirection, TextShadow}; use api::{TileOffset, TransformStyle, WorldPixel, YuvColorSpace, YuvData}; @@ -199,21 +199,22 @@ impl FrameBuilder { /// sub-primitives. fn create_primitive(&mut self, clip_and_scroll: ClipAndScrollInfo, - rect: &LayerRect, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, mut clip_sources: Vec, container: PrimitiveContainer) -> PrimitiveIndex { self.create_clip_scroll_group_if_necessary(clip_and_scroll); - if let &LocalClip::RoundedRect(main, region) = local_clip { + let local_clip = info.local_clip.unwrap(); + if let &LocalClip::RoundedRect(main, region) = &local_clip { clip_sources.push(ClipSource::Rectangle(main)); clip_sources.push(ClipSource::RoundedRectangle(region.rect, region.radii, ClipMode::Clip)); } let clip_sources = self.clip_store.insert(ClipSources::new(clip_sources)); - let prim_index = self.prim_store.add_primitive(rect, + let prim_index = self.prim_store.add_primitive(&info.rect, &local_clip.clip_rect(), + info.is_backface_visible, clip_sources, container); @@ -243,13 +244,11 @@ impl FrameBuilder { /// to the draw list. pub fn add_primitive(&mut self, clip_and_scroll: ClipAndScrollInfo, - rect: &LayerRect, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, clip_sources: Vec, container: PrimitiveContainer) -> PrimitiveIndex { let prim_index = self.create_primitive(clip_and_scroll, - rect, - local_clip, + info, clip_sources, container); @@ -280,7 +279,8 @@ impl FrameBuilder { reference_frame_offset: &LayerVector2D, pipeline_id: PipelineId, composite_ops: CompositeOps, - transform_style: TransformStyle) { + transform_style: TransformStyle, + is_backface_visible: bool) { if let Some(parent_index) = self.stacking_context_stack.last() { let parent_is_root = self.stacking_context_store[parent_index.0].is_page_root; @@ -303,7 +303,8 @@ impl FrameBuilder { !self.has_root_stacking_context, reference_frame_id, transform_style, - composite_ops)); + composite_ops, + is_backface_visible)); self.has_root_stacking_context = true; self.cmds.push(PrimitiveRunCmd::PushStackingContext(stacking_context_index)); self.stacking_context_stack.push(stacking_context_index); @@ -437,7 +438,7 @@ impl FrameBuilder { pub fn push_text_shadow(&mut self, shadow: TextShadow, clip_and_scroll: ClipAndScrollInfo, - local_clip: &LocalClip) { + info: &LayerPrimitiveInfo) { let prim = TextShadowPrimitiveCpu { shadow, primitives: Vec::new(), @@ -449,8 +450,7 @@ impl FrameBuilder { // before any visual text elements that are added as // part of this text-shadow context. let prim_index = self.add_primitive(clip_and_scroll, - &LayerRect::zero(), - local_clip, + info, Vec::new(), PrimitiveContainer::TextShadow(prim)); @@ -474,8 +474,7 @@ impl FrameBuilder { pub fn add_solid_rectangle(&mut self, clip_and_scroll: ClipAndScrollInfo, - rect: &LayerRect, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, color: &ColorF, flags: PrimitiveFlags) { let prim = RectanglePrimitive { @@ -483,8 +482,7 @@ impl FrameBuilder { }; let prim_index = self.add_primitive(clip_and_scroll, - rect, - local_clip, + info, Vec::new(), PrimitiveContainer::Rectangle(prim)); @@ -502,7 +500,7 @@ impl FrameBuilder { pub fn add_line(&mut self, clip_and_scroll: ClipAndScrollInfo, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, baseline: f32, start: f32, end: f32, @@ -538,16 +536,18 @@ impl FrameBuilder { for shadow in fast_text_shadow_prims { let mut line = line.clone(); line.color = shadow.color; + let mut info = info.clone(); + info.rect = new_rect.translate(&shadow.offset); self.add_primitive(clip_and_scroll, - &new_rect.translate(&shadow.offset), - local_clip, + &info, Vec::new(), PrimitiveContainer::Line(line)); } + let mut info = info.clone(); + info.rect = new_rect; let prim_index = self.create_primitive(clip_and_scroll, - &new_rect, - local_clip, + &info, Vec::new(), PrimitiveContainer::Line(line)); @@ -572,11 +572,11 @@ impl FrameBuilder { pub fn add_border(&mut self, clip_and_scroll: ClipAndScrollInfo, - rect: LayerRect, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, border_item: &BorderDisplayItem, gradient_stops: ItemRange, gradient_stops_count: usize) { + let rect = info.rect; let create_segments = |outset: SideOffsets2D| { // Calculate the modified rect as specific by border-image-outset let origin = LayerPoint::new(rect.origin.x - outset.left, @@ -718,9 +718,10 @@ impl FrameBuilder { } for segment in segments { + let mut info = info.clone(); + info.rect = segment.geom_rect; self.add_image(clip_and_scroll, - segment.geom_rect, - local_clip, + &info, &segment.stretch_size, &segment.tile_spacing, Some(segment.sub_rect), @@ -730,19 +731,19 @@ impl FrameBuilder { } } BorderDetails::Normal(ref border) => { - self.add_normal_border(&rect, + self.add_normal_border(info, border, &border_item.widths, - clip_and_scroll, - local_clip); + clip_and_scroll); } BorderDetails::Gradient(ref border) => { for segment in create_segments(border.outset) { let segment_rel = segment.origin - rect.origin; + let mut info = info.clone(); + info.rect = segment; self.add_gradient(clip_and_scroll, - segment, - local_clip, + &info, border.gradient.start_point - segment_rel, border.gradient.end_point - segment_rel, gradient_stops, @@ -755,10 +756,11 @@ impl FrameBuilder { BorderDetails::RadialGradient(ref border) => { for segment in create_segments(border.outset) { let segment_rel = segment.origin - rect.origin; + let mut info = info.clone(); + info.rect = segment; self.add_radial_gradient(clip_and_scroll, - segment, - local_clip, + &info, border.gradient.start_center - segment_rel, border.gradient.start_radius, border.gradient.end_center - segment_rel, @@ -775,8 +777,7 @@ impl FrameBuilder { pub fn add_gradient(&mut self, clip_and_scroll: ClipAndScrollInfo, - rect: LayerRect, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, start_point: LayerPoint, end_point: LayerPoint, stops: ItemRange, @@ -785,15 +786,15 @@ impl FrameBuilder { tile_size: LayerSize, tile_spacing: LayerSize) { let tile_repeat = tile_size + tile_spacing; - let is_not_tiled = tile_repeat.width >= rect.size.width && - tile_repeat.height >= rect.size.height; + let is_not_tiled = tile_repeat.width >= info.rect.size.width && + tile_repeat.height >= info.rect.size.height; let aligned_and_fills_rect = (start_point.x == end_point.x && start_point.y.min(end_point.y) <= 0.0 && - start_point.y.max(end_point.y) >= rect.size.height) || + start_point.y.max(end_point.y) >= info.rect.size.height) || (start_point.y == end_point.y && start_point.x.min(end_point.x) <= 0.0 && - start_point.x.max(end_point.x) >= rect.size.width); + start_point.x.max(end_point.x) >= info.rect.size.width); // Fast path for clamped, axis-aligned gradients, with gradient lines intersecting all of rect: let aligned = extend_mode == ExtendMode::Clamp && is_not_tiled && aligned_and_fills_rect; @@ -836,13 +837,12 @@ impl FrameBuilder { PrimitiveContainer::AngleGradient(gradient_cpu) }; - self.add_primitive(clip_and_scroll, &rect, local_clip, Vec::new(), prim); + self.add_primitive(clip_and_scroll, info, Vec::new(), prim); } pub fn add_radial_gradient(&mut self, clip_and_scroll: ClipAndScrollInfo, - rect: LayerRect, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, start_center: LayerPoint, start_radius: f32, end_center: LayerPoint, @@ -866,8 +866,7 @@ impl FrameBuilder { }; self.add_primitive(clip_and_scroll, - &rect, - local_clip, + info, Vec::new(), PrimitiveContainer::RadialGradient(radial_gradient_cpu)); } @@ -875,13 +874,13 @@ impl FrameBuilder { pub fn add_text(&mut self, clip_and_scroll: ClipAndScrollInfo, run_offset: LayoutVector2D, - rect: LayerRect, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, font: &FontInstance, color: &ColorF, glyph_range: ItemRange, glyph_count: usize, glyph_options: Option) { + let rect = info.rect; // Trivial early out checks if font.size.0 <= 0 { return @@ -977,9 +976,11 @@ impl FrameBuilder { } } for text_prim in fast_text_shadow_prims { + let rect = info.rect; + let mut info = info.clone(); + info.rect = rect.translate(&text_prim.offset); self.add_primitive(clip_and_scroll, - &rect.translate(&text_prim.offset), - local_clip, + &info, Vec::new(), PrimitiveContainer::TextRun(text_prim)); } @@ -987,8 +988,7 @@ impl FrameBuilder { // Create (and add to primitive store) the primitive that will be // used for both the visual element and also the shadow(s). let prim_index = self.create_primitive(clip_and_scroll, - &rect, - local_clip, + info, Vec::new(), PrimitiveContainer::TextRun(prim)); @@ -1021,9 +1021,8 @@ impl FrameBuilder { pub fn fill_box_shadow_rect(&mut self, clip_and_scroll: ClipAndScrollInfo, - box_bounds: &LayerRect, + info: &LayerPrimitiveInfo, bs_rect: LayerRect, - local_clip: &LocalClip, color: &ColorF, border_radius: f32, clip_mode: BoxShadowClipMode) { @@ -1031,7 +1030,7 @@ impl FrameBuilder { let (bs_clip_mode, rect_to_draw) = match clip_mode { BoxShadowClipMode::Outset | BoxShadowClipMode::None => (ClipMode::Clip, bs_rect), - BoxShadowClipMode::Inset => (ClipMode::ClipOut, *box_bounds), + BoxShadowClipMode::Inset => (ClipMode::ClipOut, info.rect), }; let box_clip_mode = !bs_clip_mode; @@ -1039,23 +1038,24 @@ impl FrameBuilder { // Clip the inside and then the outside of the box. let border_radius = BorderRadius::uniform(border_radius); let extra_clips = vec![ClipSource::RoundedRectangle(bs_rect, border_radius, bs_clip_mode), - ClipSource::RoundedRectangle(*box_bounds, border_radius, box_clip_mode)]; + ClipSource::RoundedRectangle(info.rect, border_radius, box_clip_mode)]; let prim = RectanglePrimitive { color: *color, }; + let mut info = info.clone(); + info.rect = rect_to_draw; + self.add_primitive(clip_and_scroll, - &rect_to_draw, - local_clip, + &info, extra_clips, PrimitiveContainer::Rectangle(prim)); } pub fn add_box_shadow(&mut self, clip_and_scroll: ClipAndScrollInfo, - box_bounds: &LayerRect, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, box_offset: &LayerVector2D, color: &ColorF, blur_radius: f32, @@ -1074,8 +1074,8 @@ impl FrameBuilder { BoxShadowClipMode::Inset => -spread_radius, }; - let bs_rect = box_bounds.translate(box_offset) - .inflate(inflate_amount, inflate_amount); + let bs_rect = info.rect.translate(box_offset) + .inflate(inflate_amount, inflate_amount); // If we have negative inflate amounts. // Have to explicitly check this since euclid::TypedRect relies on negative rects let bs_rect_empty = bs_rect.size.width <= 0.0 || bs_rect.size.height <= 0.0; @@ -1084,8 +1084,7 @@ impl FrameBuilder { if (blur_radius == 0.0 && spread_radius == 0.0 && clip_mode == BoxShadowClipMode::None) || bs_rect_empty { self.add_solid_rectangle(clip_and_scroll, - box_bounds, - local_clip, + info, color, PrimitiveFlags::None); return; @@ -1093,9 +1092,8 @@ impl FrameBuilder { if blur_radius == 0.0 && border_radius != 0.0 { self.fill_box_shadow_rect(clip_and_scroll, - box_bounds, + info, bs_rect, - local_clip, color, border_radius, clip_mode); @@ -1123,8 +1121,8 @@ impl FrameBuilder { // the original box in order to draw where the border // corners are. A clip-out mask applied below will // ensure that we don't draw on the box itself. - let inner_box_bounds = box_bounds.inflate(-border_radius, - -border_radius); + let inner_box_bounds = info.rect.inflate(-border_radius, + -border_radius); // For outset shadows, subtracting the element rectangle // from the outer rectangle gives the rectangles we need // to draw. In the simple case (no blur radius), we can @@ -1154,10 +1152,10 @@ impl FrameBuilder { // the element rect? let mut rects = Vec::new(); if edge_size == 0.0 { - subtract_rect(box_bounds, &bs_rect, &mut rects); + subtract_rect(&info.rect, &bs_rect, &mut rects); BoxShadowKind::Simple(rects) } else { - rects.push(*box_bounds); + rects.push(info.rect); BoxShadowKind::Shadow(rects) } } @@ -1166,9 +1164,10 @@ impl FrameBuilder { match shadow_kind { BoxShadowKind::Simple(rects) => { for rect in &rects { + let mut info = info.clone(); + info.rect = *rect; self.add_solid_rectangle(clip_and_scroll, - rect, - local_clip, + &info, color, PrimitiveFlags::None) } @@ -1177,9 +1176,8 @@ impl FrameBuilder { assert!(blur_radius > 0.0); if clip_mode == BoxShadowClipMode::Inset { self.fill_box_shadow_rect(clip_and_scroll, - box_bounds, + info, bs_rect, - local_clip, color, border_radius, clip_mode); @@ -1199,13 +1197,13 @@ impl FrameBuilder { let mut extra_clips = Vec::new(); if border_radius >= 0.0 { - extra_clips.push(ClipSource::RoundedRectangle(*box_bounds, + extra_clips.push(ClipSource::RoundedRectangle(info.rect, BorderRadius::uniform(border_radius), extra_clip_mode)); } let prim_cpu = BoxShadowPrimitiveCpu { - src_rect: *box_bounds, + src_rect: info.rect, bs_rect, color: *color, blur_radius, @@ -1216,9 +1214,10 @@ impl FrameBuilder { render_task_id: None, }; + let mut info = info.clone(); + info.rect = outer_rect; self.add_primitive(clip_and_scroll, - &outer_rect, - local_clip, + &info, extra_clips, PrimitiveContainer::BoxShadow(prim_cpu)); } @@ -1227,8 +1226,7 @@ impl FrameBuilder { pub fn add_image(&mut self, clip_and_scroll: ClipAndScrollInfo, - rect: LayerRect, - local_clip: &LocalClip, + info: &LayerPrimitiveInfo, stretch_size: &LayerSize, tile_spacing: &LayerSize, sub_rect: Option, @@ -1251,16 +1249,14 @@ impl FrameBuilder { }; self.add_primitive(clip_and_scroll, - &rect, - local_clip, + info, Vec::new(), PrimitiveContainer::Image(prim_cpu)); } pub fn add_yuv_image(&mut self, clip_and_scroll: ClipAndScrollInfo, - rect: LayerRect, - clip_rect: &LocalClip, + info: &LayerPrimitiveInfo, yuv_data: YuvData, color_space: YuvColorSpace, image_rendering: ImageRendering) { @@ -1278,12 +1274,11 @@ impl FrameBuilder { format, color_space, image_rendering, - gpu_block: [rect.size.width, rect.size.height, 0.0, 0.0].into(), + gpu_block: [info.rect.size.width, info.rect.size.height, 0.0, 0.0].into(), }; self.add_primitive(clip_and_scroll, - &rect, - clip_rect, + info, Vec::new(), PrimitiveContainer::YuvImage(prim_cpu)); } diff --git a/webrender/src/prim_store.rs b/webrender/src/prim_store.rs index 461bb513e2..7dcabc4241 100644 --- a/webrender/src/prim_store.rs +++ b/webrender/src/prim_store.rs @@ -142,6 +142,7 @@ pub struct PrimitiveMetadata { // storing them here. pub local_rect: LayerRect, pub local_clip_rect: LayerRect, + pub is_backface_visible: bool, } impl PrimitiveMetadata { @@ -794,6 +795,7 @@ impl PrimitiveStore { pub fn add_primitive(&mut self, local_rect: &LayerRect, local_clip_rect: &LayerRect, + is_backface_visible: bool, clip_sources: ClipSourcesHandle, container: PrimitiveContainer) -> PrimitiveIndex { let prim_index = self.cpu_metadata.len(); @@ -810,6 +812,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_rectangles.push(rect); @@ -826,6 +829,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_lines.push(line); @@ -841,6 +845,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_text_runs.push(text_cpu); @@ -856,6 +861,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_text_shadows.push(text_shadow); @@ -871,6 +877,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_images.push(image_cpu); @@ -886,6 +893,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_yuv_images.push(image_cpu); @@ -901,6 +909,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_borders.push(border_cpu); @@ -916,6 +925,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_gradients.push(gradient_cpu); @@ -932,6 +942,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_gradients.push(gradient_cpu); @@ -948,6 +959,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_radial_gradients.push(radial_gradient_cpu); @@ -963,6 +975,7 @@ impl PrimitiveStore { clip_task_id: None, local_rect: *local_rect, local_clip_rect: *local_clip_rect, + is_backface_visible: is_backface_visible, }; self.cpu_box_shadows.push(box_shadow); diff --git a/webrender/src/tiling.rs b/webrender/src/tiling.rs index 00b0547ab2..e5b852f0c0 100644 --- a/webrender/src/tiling.rs +++ b/webrender/src/tiling.rs @@ -1552,6 +1552,9 @@ pub struct StackingContext { /// Whether or not this stacking context has any visible components, calculated /// based on the size and position of all children and how they are clipped. pub is_visible: bool, + + /// Current stacking context visibility of backface. + pub is_backface_visible: bool, } impl StackingContext { @@ -1560,7 +1563,8 @@ impl StackingContext { is_page_root: bool, reference_frame_id: ClipId, transform_style: TransformStyle, - composite_ops: CompositeOps) + composite_ops: CompositeOps, + is_backface_visible: bool) -> StackingContext { let isolation = match transform_style { TransformStyle::Flat => ContextIsolation::None, @@ -1576,6 +1580,7 @@ impl StackingContext { isolation, is_page_root, is_visible: false, + is_backface_visible, } } diff --git a/webrender_api/src/display_item.rs b/webrender_api/src/display_item.rs index 833f2be63d..3607d4a831 100644 --- a/webrender_api/src/display_item.rs +++ b/webrender_api/src/display_item.rs @@ -2,8 +2,8 @@ * 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 euclid::{SideOffsets2D, TypedSideOffsets2D}; -use {ColorF, FontInstanceKey, ImageKey, LayoutPoint, LayoutRect, LayoutSize, LayoutTransform}; +use euclid::{SideOffsets2D, TypedRect, TypedSideOffsets2D}; +use {ColorF, FontInstanceKey, ImageKey, LayerPixel, LayoutPixel, LayoutPoint, LayoutRect, LayoutSize, LayoutTransform}; use {GlyphOptions, LayoutVector2D, PipelineId, PropertyBinding}; // NOTE: some of these structs have an "IMPLICIT" comment. @@ -40,11 +40,30 @@ impl ClipAndScrollInfo { #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct DisplayItem { pub item: SpecificDisplayItem, - pub rect: LayoutRect, - pub local_clip: LocalClip, pub clip_and_scroll: ClipAndScrollInfo, + pub info: LayoutPrimitiveInfo, } +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] +pub struct PrimitiveInfo { + pub rect: TypedRect, + pub local_clip: Option, + pub is_backface_visible: bool, +} + +impl LayerPrimitiveInfo { + pub fn new(rect: TypedRect) -> Self { + PrimitiveInfo { + rect: rect, + local_clip: Some(LocalClip::from(rect)), + is_backface_visible: true, + } + } +} + +pub type LayoutPrimitiveInfo = PrimitiveInfo; +pub type LayerPrimitiveInfo = PrimitiveInfo; + #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub enum SpecificDisplayItem { Clip(ClipDisplayItem), diff --git a/webrender_api/src/display_list.rs b/webrender_api/src/display_list.rs index 9a07f59cad..615d722853 100644 --- a/webrender_api/src/display_list.rs +++ b/webrender_api/src/display_list.rs @@ -10,9 +10,9 @@ use {BorderDetails, BorderDisplayItem, BorderWidths, BoxShadowClipMode, BoxShado use {ClipAndScrollInfo, ClipDisplayItem, ClipId, ColorF, ComplexClipRegion, DisplayItem}; use {ExtendMode, FastHashMap, FastHashSet, FilterOp, FontInstanceKey, GlyphIndex, GlyphInstance}; use {GlyphOptions, Gradient, GradientDisplayItem, GradientStop, IframeDisplayItem}; -use {ImageDisplayItem, ImageKey, ImageMask, ImageRendering, LayoutPoint, LayoutRect, LayoutSize}; -use {LayoutTransform, LayoutVector2D, LineDisplayItem, LineOrientation, LineStyle, LocalClip}; -use {MixBlendMode, PipelineId, PropertyBinding, PushStackingContextDisplayItem, RadialGradient}; +use {ImageDisplayItem, ImageKey, ImageMask, ImageRendering, LayerPrimitiveInfo, LayoutPoint, LayoutRect, LayoutSize}; +use {LayoutTransform, LayoutVector2D, LayoutPrimitiveInfo, LineDisplayItem, LineOrientation, LineStyle, LocalClip}; +use {MixBlendMode, PipelineId, PropertyBinding, PushStackingContextDisplayItem, PrimitiveInfo, RadialGradient}; use {RadialGradientDisplayItem, RectangleDisplayItem, ScrollFrameDisplayItem, ScrollPolicy}; use {ScrollSensitivity, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem}; use {StickyFrameInfo, TextDisplayItem, TextShadow, TransformStyle}; @@ -188,9 +188,12 @@ impl<'a> BuiltDisplayListIter<'a> { data: &data, cur_item: DisplayItem { // Dummy data, will be overwritten by `next` item: SpecificDisplayItem::PopStackingContext, - rect: LayoutRect::zero(), - local_clip: LocalClip::from(LayoutRect::zero()), clip_and_scroll: ClipAndScrollInfo::simple(ClipId::new(0, PipelineId::dummy())), + info: PrimitiveInfo { + rect: LayoutRect::zero(), + local_clip: Some(LocalClip::from(LayoutRect::zero())), + is_backface_visible: true, + }, }, cur_stops: ItemRange::default(), cur_glyphs: ItemRange::default(), @@ -319,15 +322,20 @@ impl<'a, 'b> DisplayItemRef<'a, 'b> { } pub fn rect(&self) -> LayoutRect { - self.iter.cur_item.rect + self.iter.cur_item.info.rect } - pub fn local_clip(&self) -> &LocalClip { - &self.iter.cur_item.local_clip + pub fn get_layer_primitive_info(&self, offset: &LayoutVector2D) -> LayerPrimitiveInfo { + let info = self.iter.cur_item.info; + LayerPrimitiveInfo { + rect: info.rect.translate(&offset), + local_clip: info.local_clip.map(|clip| clip.create_with_offset(offset)), + is_backface_visible: info.is_backface_visible, + } } - pub fn local_clip_with_offset(&self, offset: &LayoutVector2D) -> LocalClip { - self.iter.cur_item.local_clip.create_with_offset(offset) + pub fn local_clip(&self) -> &LocalClip { + self.iter.cur_item.info.local_clip.as_ref().unwrap() } pub fn clip_and_scroll(&self) -> ClipAndScrollInfo { @@ -358,6 +366,10 @@ impl<'a, 'b> DisplayItemRef<'a, 'b> { self.iter.display_list() } + pub fn is_backface_visible(&self) -> bool { + self.iter.cur_item.info.is_backface_visible + } + // Creates a new iterator where this element's iterator is, to hack around borrowck. pub fn sub_iter(&self) -> BuiltDisplayListIter<'a> { BuiltDisplayListIter::new_with_list_and_data(self.iter.list, self.iter.data) @@ -505,23 +517,22 @@ impl DisplayListBuilder { fn push_item(&mut self, item: SpecificDisplayItem, - rect: LayoutRect, - local_clip: Option) { - let local_clip = local_clip.unwrap_or_else(|| LocalClip::from(rect)); + info: &LayoutPrimitiveInfo) { + let mut new_info = info.clone(); + new_info.local_clip = info.local_clip.or(Some(LocalClip::from(info.rect))); bincode::serialize_into(&mut self.data, &DisplayItem { item, - rect, - local_clip: local_clip, clip_and_scroll: *self.clip_stack.last().unwrap(), + info: new_info, }, bincode::Infinite).unwrap(); } fn push_new_empty_item(&mut self, item: SpecificDisplayItem) { + let info = LayoutPrimitiveInfo::new(LayoutRect::zero()); bincode::serialize_into(&mut self.data, &DisplayItem { item, - rect: LayoutRect::zero(), - local_clip: LocalClip::from(LayoutRect::zero()), clip_and_scroll: *self.clip_stack.last().unwrap(), + info, }, bincode::Infinite).unwrap(); } @@ -543,16 +554,18 @@ impl DisplayListBuilder { debug_assert_eq!(len, count); } - pub fn push_rect(&mut self, rect: LayoutRect, local_clip: Option, color: ColorF) { + pub fn push_rect(&mut self, + info: &LayoutPrimitiveInfo, + color: ColorF) { let item = SpecificDisplayItem::Rectangle(RectangleDisplayItem { color, }); - self.push_item(item, rect, local_clip); + self.push_item(item, info); } pub fn push_line(&mut self, - local_clip: Option, + info: &LayoutPrimitiveInfo, baseline: f32, start: f32, end: f32, @@ -565,12 +578,11 @@ impl DisplayListBuilder { width, color, style, }); - self.push_item(item, LayoutRect::zero(), local_clip); + self.push_item(item, info); } pub fn push_image(&mut self, - rect: LayoutRect, - local_clip: Option, + info: &LayoutPrimitiveInfo, stretch_size: LayoutSize, tile_spacing: LayoutSize, image_rendering: ImageRendering, @@ -582,13 +594,12 @@ impl DisplayListBuilder { image_rendering, }); - self.push_item(item, rect, local_clip); + self.push_item(item, info); } /// Push a yuv image. All planar data in yuv image should use the same buffer type. pub fn push_yuv_image(&mut self, - rect: LayoutRect, - local_clip: Option, + info: &LayoutPrimitiveInfo, yuv_data: YuvData, color_space: YuvColorSpace, image_rendering: ImageRendering) { @@ -597,12 +608,11 @@ impl DisplayListBuilder { color_space, image_rendering, }); - self.push_item(item, rect, local_clip); + self.push_item(item, info); } pub fn push_text(&mut self, - rect: LayoutRect, - local_clip: Option, + info: &LayoutPrimitiveInfo, glyphs: &[GlyphInstance], font_key: FontInstanceKey, color: ColorF, @@ -614,7 +624,7 @@ impl DisplayListBuilder { }); for split_glyphs in glyphs.chunks(MAX_TEXT_RUN_LENGTH) { - self.push_item(item, rect, local_clip); + self.push_item(item, info); self.push_iter(split_glyphs); // Remember that we've seen these glyphs @@ -804,8 +814,7 @@ impl DisplayListBuilder { } pub fn push_border(&mut self, - rect: LayoutRect, - local_clip: Option, + info: &LayoutPrimitiveInfo, widths: BorderWidths, details: BorderDetails) { let item = SpecificDisplayItem::Border(BorderDisplayItem { @@ -813,12 +822,11 @@ impl DisplayListBuilder { widths, }); - self.push_item(item, rect, local_clip); + self.push_item(item, info); } pub fn push_box_shadow(&mut self, - rect: LayoutRect, - local_clip: Option, + info: &LayoutPrimitiveInfo, box_bounds: LayoutRect, offset: LayoutVector2D, color: ColorF, @@ -836,12 +844,11 @@ impl DisplayListBuilder { clip_mode, }); - self.push_item(item, rect, local_clip); + self.push_item(item, info); } pub fn push_gradient(&mut self, - rect: LayoutRect, - local_clip: Option, + info: &LayoutPrimitiveInfo, gradient: Gradient, tile_size: LayoutSize, tile_spacing: LayoutSize) { @@ -851,12 +858,11 @@ impl DisplayListBuilder { tile_spacing, }); - self.push_item(item, rect, local_clip); + self.push_item(item, info); } pub fn push_radial_gradient(&mut self, - rect: LayoutRect, - local_clip: Option, + info: &LayoutPrimitiveInfo, gradient: RadialGradient, tile_size: LayoutSize, tile_spacing: LayoutSize) { @@ -866,12 +872,12 @@ impl DisplayListBuilder { tile_spacing, }); - self.push_item(item, rect, local_clip); + self.push_item(item, info); } pub fn push_stacking_context(&mut self, + info: &LayoutPrimitiveInfo, scroll_policy: ScrollPolicy, - bounds: LayoutRect, transform: Option>, transform_style: TransformStyle, perspective: Option, @@ -887,7 +893,7 @@ impl DisplayListBuilder { } }); - self.push_item(item, bounds, None); + self.push_item(item, info); self.push_iter(&filters); } @@ -928,7 +934,13 @@ impl DisplayListBuilder { scroll_sensitivity, }); - self.push_item(item, content_rect, Some(LocalClip::from(clip_rect))); + let info = LayoutPrimitiveInfo { + rect: content_rect, + local_clip: Some(LocalClip::from(clip_rect)), + is_backface_visible: true, + }; + + self.push_item(item, &info); self.push_iter(complex_clips); id } @@ -948,7 +960,9 @@ impl DisplayListBuilder { image_mask: image_mask, }); - self.push_item(item, clip_rect, Some(LocalClip::from(clip_rect))); + let info = LayoutPrimitiveInfo::new(clip_rect); + + self.push_item(item, &info); self.push_iter(complex_clips); id } @@ -964,7 +978,13 @@ impl DisplayListBuilder { sticky_frame_info, }); - self.push_item(item, frame_rect, None); + let info = LayoutPrimitiveInfo { + rect: frame_rect, + local_clip: None, + is_backface_visible: true, + }; + + self.push_item(item, &info); id } @@ -982,11 +1002,10 @@ impl DisplayListBuilder { } pub fn push_iframe(&mut self, - rect: LayoutRect, - local_clip: Option, + info: &LayoutPrimitiveInfo, pipeline_id: PipelineId) { let item = SpecificDisplayItem::Iframe(IframeDisplayItem { pipeline_id: pipeline_id }); - self.push_item(item, rect, local_clip); + self.push_item(item, info); } // Don't use this function. It will go away. @@ -1009,12 +1028,9 @@ impl DisplayListBuilder { } pub fn push_text_shadow(&mut self, - rect: LayoutRect, - local_clip: Option, + info: &LayoutPrimitiveInfo, shadow: TextShadow) { - self.push_item(SpecificDisplayItem::PushTextShadow(shadow), - rect, - local_clip); + self.push_item(SpecificDisplayItem::PushTextShadow(shadow), info); } pub fn pop_text_shadow(&mut self) { diff --git a/webrender_api/src/units.rs b/webrender_api/src/units.rs index 443e175fe0..137939ead6 100644 --- a/webrender_api/src/units.rs +++ b/webrender_api/src/units.rs @@ -46,7 +46,7 @@ pub type LayoutVector3D = LayerVector3D; pub type LayoutSize = LayerSize; /// Geometry in a layer's local coordinate space (logical pixels). -#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Deserialize, Serialize)] pub struct LayerPixel; pub type LayerRect = TypedRect; diff --git a/wrench/src/rawtest.rs b/wrench/src/rawtest.rs index 619cb97e69..8c47090c69 100644 --- a/wrench/src/rawtest.rs +++ b/wrench/src/rawtest.rs @@ -62,10 +62,15 @@ impl<'a> RawtestHarness<'a> { let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size); + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(448.899994, 74.0), LayoutSize::new(151.000031, 56.)), + local_clip: None, + is_backface_visible: true, + }; + // setup some malicious image size parameters builder.push_image( - LayoutRect::new(LayoutPoint::new(448.899994, 74.0), LayoutSize::new(151.000031, 56.)), - None, + &info, LayoutSize::new(151., 56.0), LayoutSize::new(151.0, 56.0), ImageRendering::Auto, @@ -111,9 +116,14 @@ impl<'a> RawtestHarness<'a> { // draw the blob the first time let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size); + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(0.0, 60.0), LayoutSize::new(200.0, 200.0)), + local_clip: None, + is_backface_visible: true, + }; + builder.push_image( - LayoutRect::new(LayoutPoint::new(0.0, 60.0), LayoutSize::new(200.0, 200.0)), - None, + &info, LayoutSize::new(200.0, 200.0), LayoutSize::new(0.0, 0.0), ImageRendering::Auto, @@ -134,9 +144,13 @@ impl<'a> RawtestHarness<'a> { // make a new display list that refers to the first image let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size); + let info = LayoutPrimitiveInfo { + rect: LayoutRect::new(LayoutPoint::new(1.0, 60.0), LayoutSize::new(200.0, 200.0)), + local_clip: None, + is_backface_visible: true, + }; builder.push_image( - LayoutRect::new(LayoutPoint::new(1.0, 60.0), LayoutSize::new(200.0, 200.0)), - None, + &info, LayoutSize::new(200.0, 200.0), LayoutSize::new(0.0, 0.0), ImageRendering::Auto, diff --git a/wrench/src/yaml_frame_reader.rs b/wrench/src/yaml_frame_reader.rs index 9016356d5e..1886d1f9bb 100644 --- a/wrench/src/yaml_frame_reader.rs +++ b/wrench/src/yaml_frame_reader.rs @@ -137,7 +137,8 @@ impl YamlFrameReader { let content_size = self.get_root_size_from_yaml(wrench, pipeline); let mut dl = DisplayListBuilder::new(pipeline_id, content_size); - self.add_stacking_context_from_yaml(&mut dl, wrench, pipeline, true); + let mut info = LayoutPrimitiveInfo::new(LayoutRect::zero()); + self.add_stacking_context_from_yaml(&mut dl, wrench, pipeline, true, &mut info); self.display_lists.push(dl.finalize()); } } @@ -145,7 +146,8 @@ impl YamlFrameReader { assert!(!yaml["root"].is_badvalue(), "Missing root stacking context"); let content_size = self.get_root_size_from_yaml(wrench, &yaml["root"]); let mut dl = DisplayListBuilder::new(wrench.root_pipeline_id, content_size); - self.add_stacking_context_from_yaml(&mut dl, wrench, &yaml["root"], true); + let mut info = LayoutPrimitiveInfo::new(LayoutRect::zero()); + self.add_stacking_context_from_yaml(&mut dl, wrench, &yaml["root"], true, &mut info); self.display_lists.push(dl.finalize()); } @@ -280,14 +282,14 @@ impl YamlFrameReader { } } - fn handle_rect(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, local_clip: LocalClip) { + fn handle_rect(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { let bounds_key = if item["type"].is_badvalue() { "rect" } else { "bounds" }; - let rect = item[bounds_key].as_rect().expect("rect type must have bounds"); + info.rect = item[bounds_key].as_rect().expect("rect type must have bounds"); let color = item["color"].as_colorf().unwrap_or(*WHITE_COLOR); - dl.push_rect(rect, Some(local_clip), color); + dl.push_rect(&info, color); } - fn handle_line(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, local_clip: LocalClip) { + fn handle_line(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { let color = item["color"].as_colorf().unwrap_or(*BLACK_COLOR); let baseline = item["baseline"].as_f32().expect("line must have baseline"); let start = item["start"].as_f32().expect("line must have start"); @@ -297,32 +299,38 @@ impl YamlFrameReader { .expect("line must have orientation"); let style = item["style"].as_str().and_then(LineStyle::from_str) .expect("line must have style"); - dl.push_line(Some(local_clip), baseline, start, end, orientation, width, color, style); + dl.push_line(&info, baseline, start, end, orientation, width, color, style); } - fn handle_gradient(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, local_clip: LocalClip) { + fn handle_gradient(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { let bounds_key = if item["type"].is_badvalue() { "gradient" } else { "bounds" }; let bounds = item[bounds_key].as_rect().expect("gradient must have bounds"); + info.rect = bounds; let gradient = self.to_gradient(dl, item); let tile_size = item["tile-size"].as_size().unwrap_or(bounds.size); let tile_spacing = item["tile-spacing"].as_size().unwrap_or(LayoutSize::zero()); - dl.push_gradient(bounds, Some(local_clip), gradient, tile_size, tile_spacing); + dl.push_gradient(&info, gradient, tile_size, tile_spacing); } - fn handle_radial_gradient(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, local_clip: LocalClip) { + fn handle_radial_gradient(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { let bounds_key = if item["type"].is_badvalue() { "radial-gradient" } else { "bounds" }; let bounds = item[bounds_key].as_rect().expect("radial gradient must have bounds"); + info.rect = bounds; let gradient = self.to_radial_gradient(dl, item); let tile_size = item["tile-size"].as_size().unwrap_or(bounds.size); let tile_spacing = item["tile-spacing"].as_size().unwrap_or(LayoutSize::zero()); - dl.push_radial_gradient(bounds, Some(local_clip), gradient, tile_size, tile_spacing); + dl.push_radial_gradient(&info, gradient, tile_size, tile_spacing); } - fn handle_border(&mut self, dl: &mut DisplayListBuilder, wrench: &mut Wrench, item: &Yaml, local_clip: LocalClip) { + fn handle_border(&mut self, + dl: &mut DisplayListBuilder, + wrench: &mut Wrench, + item: &Yaml, + info: &mut LayoutPrimitiveInfo) { let bounds_key = if item["type"].is_badvalue() { "border" } else { "bounds" }; - let bounds = item[bounds_key].as_rect().expect("borders must have bounds"); + info.rect = item[bounds_key].as_rect().expect("borders must have bounds"); let widths = item["width"].as_vec_f32().expect("borders must have width(s)"); let widths = broadcast(&widths, 4); let widths = BorderWidths { top: widths[0], left: widths[1], bottom: widths[2], right: widths[3] }; @@ -430,13 +438,14 @@ impl YamlFrameReader { None }; if let Some(details) = border_details { - dl.push_border(bounds, Some(local_clip), widths, details); + dl.push_border(&info, widths, details); } } - fn handle_box_shadow(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, local_clip: LocalClip) { + fn handle_box_shadow(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { let bounds_key = if item["type"].is_badvalue() { "box-shadow" } else { "bounds" }; let bounds = item[bounds_key].as_rect().expect("box shadow must have bounds"); + info.rect = bounds; let box_bounds = item["box-bounds"].as_rect().unwrap_or(bounds); let offset = item["offset"].as_vector().unwrap_or(LayoutVector2D::zero()); let color = item["color"].as_colorf().unwrap_or(ColorF::new(0.0, 0.0, 0.0, 1.0)); @@ -454,8 +463,7 @@ impl YamlFrameReader { BoxShadowClipMode::None }; - dl.push_box_shadow(bounds, - Some(local_clip), + dl.push_box_shadow(&info, box_bounds, offset, color, @@ -465,13 +473,17 @@ impl YamlFrameReader { clip_mode); } - fn handle_image(&mut self, dl: &mut DisplayListBuilder, wrench: &mut Wrench, item: &Yaml, local_clip: LocalClip) { + fn handle_image(&mut self, + dl: &mut DisplayListBuilder, + wrench: &mut Wrench, + item: &Yaml, + info: &mut LayoutPrimitiveInfo) { let filename = &item[if item["type"].is_badvalue() { "image" } else { "src" }]; let tiling = item["tile-size"].as_i64(); let (image_key, image_dims) = wrench.add_or_get_image(&rsrc_path(filename, &self.aux_dir), tiling); let bounds_raws = item["bounds"].as_vec_f32().unwrap(); - let bounds = if bounds_raws.len() == 2 { + info.rect = if bounds_raws.len() == 2 { LayoutRect::new(LayoutPoint::new(bounds_raws[0], bounds_raws[1]), image_dims) } else if bounds_raws.len() == 4 { @@ -491,15 +503,18 @@ impl YamlFrameReader { Some("pixelated") => ImageRendering::Pixelated, Some(_) => panic!("ImageRendering can be auto, crisp-edges, or pixelated -- got {:?}", item), }; - dl.push_image(bounds, - Some(local_clip), + dl.push_image(&info, stretch_size, tile_spacing, rendering, image_key); } - fn handle_text(&mut self, dl: &mut DisplayListBuilder, wrench: &mut Wrench, item: &Yaml, local_clip: LocalClip) { + fn handle_text(&mut self, + dl: &mut DisplayListBuilder, + wrench: &mut Wrench, + item: &Yaml, + info: &mut LayoutPrimitiveInfo) { let size = item["size"].as_pt_to_au().unwrap_or(Au::from_f32_px(16.0)); let color = item["color"].as_colorf().unwrap_or(*BLACK_COLOR); @@ -552,19 +567,19 @@ impl YamlFrameReader { let rect = LayoutRect::new(LayoutPoint::new(0.0, 0.0), wrench.window_size_f32()); (glyphs, rect) }; + info.rect = rect; - dl.push_text(rect, - Some(local_clip), + dl.push_text(&info, &glyphs, font_instance_key, color, None); } - fn handle_iframe(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, local_clip: LocalClip) { - let bounds = item["bounds"].as_rect().expect("iframe must have bounds"); + fn handle_iframe(&mut self, dl: &mut DisplayListBuilder, item: &Yaml, info: &mut LayoutPrimitiveInfo) { + info.rect = item["bounds"].as_rect().expect("iframe must have bounds"); let pipeline_id = item["id"].as_pipeline_id().unwrap(); - dl.push_iframe(bounds, Some(local_clip), pipeline_id); + dl.push_iframe(&info, pipeline_id); } pub fn get_local_clip_for_item(&mut self, yaml: &Yaml, full_clip: LayoutRect) -> LocalClip { @@ -616,23 +631,28 @@ impl YamlFrameReader { if let Some(clip_scroll_info) = clip_scroll_info { dl.push_clip_and_scroll_info(clip_scroll_info); } - let local_clip = self.get_local_clip_for_item(item, full_clip); + let backface_visible = item["backface-visible"].as_bool().unwrap_or(true); + let mut info = LayoutPrimitiveInfo { + rect: LayoutRect::zero(), + local_clip: Some(local_clip), + is_backface_visible: backface_visible, + }; match item_type { - "rect" => self.handle_rect(dl, item, local_clip), - "line" => self.handle_line(dl, item, local_clip), - "image" => self.handle_image(dl, wrench, item, local_clip), - "text" | "glyphs" => self.handle_text(dl, wrench, item, local_clip), + "rect" => self.handle_rect(dl, item, &mut info), + "line" => self.handle_line(dl, item, &mut info), + "image" => self.handle_image(dl, wrench, item, &mut info), + "text" | "glyphs" => self.handle_text(dl, wrench, item, &mut info), "scroll-frame" => self.handle_scroll_frame(dl, wrench, item), "sticky-frame" => self.handle_sticky_frame(dl, wrench, item), "clip" => self.handle_clip(dl, wrench, item), - "border" => self.handle_border(dl, wrench, item, local_clip), - "gradient" => self.handle_gradient(dl, item, local_clip), - "radial-gradient" => self.handle_radial_gradient(dl, item, local_clip), - "box-shadow" => self.handle_box_shadow(dl, item, local_clip), - "iframe" => self.handle_iframe(dl, item, local_clip), - "stacking-context" => self.add_stacking_context_from_yaml(dl, wrench, item, false), - "text-shadow" => self.handle_push_text_shadow(dl, item), + "border" => self.handle_border(dl, wrench, item, &mut info), + "gradient" => self.handle_gradient(dl, item, &mut info), + "radial-gradient" => self.handle_radial_gradient(dl, item, &mut info), + "box-shadow" => self.handle_box_shadow(dl, item, &mut info), + "iframe" => self.handle_iframe(dl, item, &mut info), + "stacking-context" => self.add_stacking_context_from_yaml(dl, wrench, item, false, &mut info), + "text-shadow" => self.handle_push_text_shadow(dl, item, &mut info), "pop-text-shadow" => self.handle_pop_text_shadow(dl), _ => println!("Skipping unknown item type: {:?}", item), } @@ -683,15 +703,19 @@ impl YamlFrameReader { dl.pop_clip_id(); } - pub fn handle_push_text_shadow(&mut self, dl: &mut DisplayListBuilder, yaml: &Yaml) { + pub fn handle_push_text_shadow(&mut self, + dl: &mut DisplayListBuilder, + yaml: &Yaml, + info: &mut LayoutPrimitiveInfo) { let rect = yaml["bounds"].as_rect() .expect("Text shadows require bounds"); + info.rect = rect; + info.local_clip = None; let blur_radius = yaml["blur-radius"].as_f32().unwrap_or(0.0); let offset = yaml["offset"].as_vector().unwrap_or(LayoutVector2D::zero()); let color = yaml["color"].as_colorf().unwrap_or(*BLACK_COLOR); - dl.push_text_shadow(rect, - None, + dl.push_text_shadow(&info, TextShadow { blur_radius, offset, color }); @@ -728,7 +752,8 @@ impl YamlFrameReader { dl: &mut DisplayListBuilder, wrench: &mut Wrench, yaml: &Yaml, - is_root: bool) { + is_root: bool, + info: &mut LayoutPrimitiveInfo) { let default_bounds = LayoutRect::new(LayoutPoint::zero(), wrench.window_size_f32()); let bounds = yaml["bounds"].as_rect().unwrap_or(default_bounds); @@ -761,9 +786,11 @@ impl YamlFrameReader { } let filters = yaml["filters"].as_vec_filter_op().unwrap_or(vec![]); + info.rect = bounds; + info.local_clip = None; - dl.push_stacking_context(scroll_policy, - bounds, + dl.push_stacking_context(&info, + scroll_policy, transform.into(), transform_style, perspective, diff --git a/wrench/src/yaml_frame_writer.rs b/wrench/src/yaml_frame_writer.rs index 35e3043ccb..76209bfbc3 100644 --- a/wrench/src/yaml_frame_writer.rs +++ b/wrench/src/yaml_frame_writer.rs @@ -594,6 +594,7 @@ impl YamlFrameWriter { (scroll_id, None) => Yaml::Integer(scroll_id), }; yaml_node(&mut v, "clip-and-scroll", clip_and_scroll_yaml); + bool_node(&mut v, "backface-visible", base.is_backface_visible()); match *base.item() { Rectangle(item) => { From dec5a43247254d1ba464f0fea46bce117f36a10f Mon Sep 17 00:00:00 2001 From: Morris Tseng Date: Thu, 24 Aug 2017 14:18:51 +0800 Subject: [PATCH 2/4] Check backface visibility. --- webrender/src/frame_builder.rs | 4 ++++ webrender/src/prim_store.rs | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/webrender/src/frame_builder.rs b/webrender/src/frame_builder.rs index 1a42dbc2e6..1cb7a5d1d9 100644 --- a/webrender/src/frame_builder.rs +++ b/webrender/src/frame_builder.rs @@ -1955,6 +1955,10 @@ impl<'a> LayerRectCalculationAndCullingPass<'a> { .expect("No display list?"); debug!("\tclip_bounds {:?}, layer_local_clip {:?}", clip_bounds, packed_layer.local_clip_rect); + if !stacking_context.is_backface_visible && packed_layer.transform.is_backface_visible() { + return; + } + for i in 0..prim_count { let prim_index = PrimitiveIndex(base_prim_index.0 + i); let prim_store = &mut self.frame_builder.prim_store; diff --git a/webrender/src/prim_store.rs b/webrender/src/prim_store.rs index 7dcabc4241..3d7e7dfeff 100644 --- a/webrender/src/prim_store.rs +++ b/webrender/src/prim_store.rs @@ -1003,6 +1003,11 @@ impl PrimitiveStore { layer_combined_local_clip_rect: &LayerRect, device_pixel_ratio: f32) -> Option<(LayerRect, DeviceIntRect)> { let metadata = &self.cpu_metadata[prim_index.0]; + + if !metadata.is_backface_visible && layer_transform.is_backface_visible() { + return None; + } + let local_rect = metadata.local_rect .intersection(&metadata.local_clip_rect) .and_then(|rect| rect.intersection(layer_combined_local_clip_rect)); From f8d76e0c25132ba4d72765923faaec43b50661fb Mon Sep 17 00:00:00 2001 From: Morris Tseng Date: Thu, 24 Aug 2017 14:16:48 +0800 Subject: [PATCH 3/4] Add test cases for backface visible. --- wrench/reftests/backface/backface-leaf.yaml | 14 ++++++++++++++ wrench/reftests/backface/backface-ref.yaml | 6 ++++++ wrench/reftests/backface/backface-sc.yaml | 14 ++++++++++++++ wrench/reftests/backface/reftest.list | 2 ++ wrench/reftests/reftest.list | 1 + 5 files changed, 37 insertions(+) create mode 100644 wrench/reftests/backface/backface-leaf.yaml create mode 100644 wrench/reftests/backface/backface-ref.yaml create mode 100644 wrench/reftests/backface/backface-sc.yaml create mode 100644 wrench/reftests/backface/reftest.list diff --git a/wrench/reftests/backface/backface-leaf.yaml b/wrench/reftests/backface/backface-leaf.yaml new file mode 100644 index 0000000000..cd588c7974 --- /dev/null +++ b/wrench/reftests/backface/backface-leaf.yaml @@ -0,0 +1,14 @@ +--- +root: + items: + - type: rect + color: red + bounds: 0 0 1024 768 + - type: stacking-context + bounds: 0 0 1024 768 + transform: rotate-x(180) + items: + - type: rect + bounds: 0 0 200 200 + color: green + backface-visible: false diff --git a/wrench/reftests/backface/backface-ref.yaml b/wrench/reftests/backface/backface-ref.yaml new file mode 100644 index 0000000000..614cf5f465 --- /dev/null +++ b/wrench/reftests/backface/backface-ref.yaml @@ -0,0 +1,6 @@ +--- +root: + items: + - type: rect + color: red + bounds: 0 0 1024 768 diff --git a/wrench/reftests/backface/backface-sc.yaml b/wrench/reftests/backface/backface-sc.yaml new file mode 100644 index 0000000000..6390cf8365 --- /dev/null +++ b/wrench/reftests/backface/backface-sc.yaml @@ -0,0 +1,14 @@ +--- +root: + items: + - type: rect + color: red + bounds: 0 0 1024 768 + - type: stacking-context + bounds: 0 0 1024 768 + transform: rotate-x(180) + backface-visible: false + items: + - type: rect + bounds: 0 0 200 200 + color: green diff --git a/wrench/reftests/backface/reftest.list b/wrench/reftests/backface/reftest.list new file mode 100644 index 0000000000..0bf20f1a66 --- /dev/null +++ b/wrench/reftests/backface/reftest.list @@ -0,0 +1,2 @@ +== backface-leaf.yaml backface-ref.yaml +== backface-sc.yaml backface-ref.yaml diff --git a/wrench/reftests/reftest.list b/wrench/reftests/reftest.list index c89dcfac56..2eda30bfa0 100644 --- a/wrench/reftests/reftest.list +++ b/wrench/reftests/reftest.list @@ -1,4 +1,5 @@ include aa/reftest.list +include backface/reftest.list include blend/reftest.list include border/reftest.list include boxshadow/reftest.list From afbc931df0a13bb17a58843ea7a5f4fe972ed0aa Mon Sep 17 00:00:00 2001 From: Morris Tseng Date: Wed, 30 Aug 2017 15:12:00 +0800 Subject: [PATCH 4/4] Update euclid version and Cargo.lock. --- Cargo.lock | 12 ++++++------ webrender/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e0b04b891..4813b1795f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "font-loader 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -306,7 +306,7 @@ dependencies = [ [[package]] name = "euclid" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -682,7 +682,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1061,7 +1061,7 @@ dependencies = [ "core-graphics 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "gamma-lut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1092,7 +1092,7 @@ dependencies = [ "core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1202,7 +1202,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a" "checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83" -"checksum euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7be9fcb1ce77782eb620253eb02bc1f000545f3c360841a26cda572f10fad4ff" +"checksum euclid 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "50c9e4c3b53de731815135191f0b77969bea953211b8bbd3cc3083a7b10e190e" "checksum expat-sys 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cef36cd1a8a02d28b91d97347c63247b9e4cb8a8e36df36f8201dc87a1c0859c" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" "checksum font-loader 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4cffa6a4953349a6dc37945f1f14228ca009e29cc7c3e9abc5fd78ac884a19a2" diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml index 8a708c368a..5de0d75efc 100644 --- a/webrender/Cargo.toml +++ b/webrender/Cargo.toml @@ -17,7 +17,7 @@ app_units = "0.5.6" bincode = "0.8" bit-set = "0.4" byteorder = "1.0" -euclid = "0.15.1" +euclid = "0.15.2" fxhash = "0.2.1" gleam = "0.4.8" lazy_static = "0.2"