From 7cda552aeba478b92fccf2aeb86ac9c8e1778a1e Mon Sep 17 00:00:00 2001 From: Andrew Osmond Date: Thu, 12 Sep 2019 12:42:37 +0000 Subject: [PATCH] Bug 1574493 - Part 1. Split out repeating and non-repeating images in the display list. r=jrmuizel Repeating/background images may have extra parameters such the stretch size and tile spacing, that non-repeating images do not require. By splitting these apart, we can make it easier to infer what we should do if snapping changes the size of an image primitive, in addition to reducing the display list size for non-repeating images. Differential Revision: https://phabricator.services.mozilla.com/D45056 --HG-- extra : moz-landing-system : lando --- gfx/webrender_bindings/WebRenderAPI.cpp | 19 ++--- gfx/webrender_bindings/WebRenderAPI.h | 11 +-- gfx/webrender_bindings/src/bindings.rs | 46 ++++++++++-- gfx/wr/examples/blob.rs | 4 -- gfx/wr/examples/frame_output.rs | 2 - gfx/wr/examples/image_resize.rs | 4 -- gfx/wr/examples/texture_cache_stress.rs | 6 -- .../webrender/src/display_list_flattener.rs | 19 +++++ gfx/wr/webrender_api/src/display_item.rs | 25 ++++++- gfx/wr/webrender_api/src/display_list.rs | 25 ++++++- .../reftests/performance/no-clip-mask.yaml | 1 + .../reftests/transforms/near-plane-clip.yaml | 1 + gfx/wr/wrench/src/rawtest.rs | 36 ++-------- gfx/wr/wrench/src/yaml_frame_reader.rs | 37 ++++++---- gfx/wr/wrench/src/yaml_frame_writer.rs | 23 ++++++ layout/painting/nsImageRenderer.cpp | 70 +++++++++---------- layout/xul/nsImageBoxFrame.cpp | 7 +- 17 files changed, 216 insertions(+), 120 deletions(-) diff --git a/gfx/webrender_bindings/WebRenderAPI.cpp b/gfx/webrender_bindings/WebRenderAPI.cpp index 95f907e429e3..19651a9bdbbc 100644 --- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -1091,14 +1091,15 @@ void DisplayListBuilder::PushImage( const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, bool aIsBackfaceVisible, wr::ImageRendering aFilter, wr::ImageKey aImage, bool aPremultipliedAlpha, const wr::ColorF& aColor) { - wr::LayoutSize size; - size.width = aBounds.size.width; - size.height = aBounds.size.height; - PushImage(aBounds, aClip, aIsBackfaceVisible, size, size, aFilter, aImage, - aPremultipliedAlpha, aColor); + wr::LayoutRect clip = MergeClipLeaf(aClip); + WRDL_LOG("PushImage b=%s cl=%s\n", mWrState, Stringify(aBounds).c_str(), + Stringify(clip).c_str()); + wr_dp_push_image(mWrState, aBounds, clip, aIsBackfaceVisible, + &mCurrentSpaceAndClipChain, aFilter, aImage, + aPremultipliedAlpha, aColor); } -void DisplayListBuilder::PushImage( +void DisplayListBuilder::PushRepeatingImage( const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, bool aIsBackfaceVisible, const wr::LayoutSize& aStretchSize, const wr::LayoutSize& aTileSpacing, wr::ImageRendering aFilter, @@ -1107,9 +1108,9 @@ void DisplayListBuilder::PushImage( WRDL_LOG("PushImage b=%s cl=%s s=%s t=%s\n", mWrState, Stringify(aBounds).c_str(), Stringify(clip).c_str(), Stringify(aStretchSize).c_str(), Stringify(aTileSpacing).c_str()); - wr_dp_push_image(mWrState, aBounds, clip, aIsBackfaceVisible, - &mCurrentSpaceAndClipChain, aStretchSize, aTileSpacing, - aFilter, aImage, aPremultipliedAlpha, aColor); + wr_dp_push_repeating_image( + mWrState, aBounds, clip, aIsBackfaceVisible, &mCurrentSpaceAndClipChain, + aStretchSize, aTileSpacing, aFilter, aImage, aPremultipliedAlpha, aColor); } void DisplayListBuilder::PushYCbCrPlanarImage( diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index 1a67f61677d6..e32cac082767 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -479,11 +479,12 @@ class DisplayListBuilder final { wr::ImageKey aImage, bool aPremultipliedAlpha = true, const wr::ColorF& aColor = wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}); - void PushImage(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, - bool aIsBackfaceVisible, const wr::LayoutSize& aStretchSize, - const wr::LayoutSize& aTileSpacing, wr::ImageRendering aFilter, - wr::ImageKey aImage, bool aPremultipliedAlpha = true, - const wr::ColorF& aColor = wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}); + void PushRepeatingImage( + const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, + bool aIsBackfaceVisible, const wr::LayoutSize& aStretchSize, + const wr::LayoutSize& aTileSpacing, wr::ImageRendering aFilter, + wr::ImageKey aImage, bool aPremultipliedAlpha = true, + const wr::ColorF& aColor = wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}); void PushYCbCrPlanarImage( const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 396e42edd922..b0d078d91f0d 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -2570,8 +2570,6 @@ pub extern "C" fn wr_dp_push_image(state: &mut WrState, clip: LayoutRect, is_backface_visible: bool, parent: &WrSpaceAndClipChain, - stretch_size: LayoutSize, - tile_spacing: LayoutSize, image_rendering: ImageRendering, key: WrImageKey, premultiplied_alpha: bool, @@ -2598,14 +2596,54 @@ pub extern "C" fn wr_dp_push_image(state: &mut WrState, .dl_builder .push_image(&prim_info, bounds, - stretch_size, - tile_spacing, image_rendering, alpha_type, key, color); } +#[no_mangle] +pub extern "C" fn wr_dp_push_repeating_image(state: &mut WrState, + bounds: LayoutRect, + clip: LayoutRect, + is_backface_visible: bool, + parent: &WrSpaceAndClipChain, + stretch_size: LayoutSize, + tile_spacing: LayoutSize, + image_rendering: ImageRendering, + key: WrImageKey, + premultiplied_alpha: bool, + color: ColorF) { + debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() }); + + let space_and_clip = parent.to_webrender(state.pipeline_id); + + let prim_info = CommonItemProperties { + clip_rect: clip, + clip_id: space_and_clip.clip_id, + spatial_id: space_and_clip.spatial_id, + is_backface_visible, + hit_info: state.current_tag, + }; + + let alpha_type = if premultiplied_alpha { + AlphaType::PremultipliedAlpha + } else { + AlphaType::Alpha + }; + + state.frame_builder + .dl_builder + .push_repeating_image(&prim_info, + bounds, + stretch_size, + tile_spacing, + image_rendering, + alpha_type, + key, + color); +} + /// Push a 3 planar yuv image. #[no_mangle] pub extern "C" fn wr_dp_push_yuv_planar_image(state: &mut WrState, diff --git a/gfx/wr/examples/blob.rs b/gfx/wr/examples/blob.rs index 01cc48cdebed..470e9587c415 100644 --- a/gfx/wr/examples/blob.rs +++ b/gfx/wr/examples/blob.rs @@ -236,8 +236,6 @@ impl Example for App { builder.push_image( &CommonItemProperties::new(bounds, space_and_clip), bounds, - LayoutSize::new(500.0, 500.0), - LayoutSize::new(0.0, 0.0), api::ImageRendering::Auto, api::AlphaType::PremultipliedAlpha, blob_img1.as_image(), @@ -248,8 +246,6 @@ impl Example for App { builder.push_image( &CommonItemProperties::new(bounds, space_and_clip), bounds, - LayoutSize::new(200.0, 200.0), - LayoutSize::new(0.0, 0.0), api::ImageRendering::Auto, api::AlphaType::PremultipliedAlpha, blob_img2.as_image(), diff --git a/gfx/wr/examples/frame_output.rs b/gfx/wr/examples/frame_output.rs index 7bdf3e17ddc1..c3e1e190b681 100644 --- a/gfx/wr/examples/frame_output.rs +++ b/gfx/wr/examples/frame_output.rs @@ -170,8 +170,6 @@ impl Example for App { builder.push_image( &CommonItemProperties::new(bounds, space_and_clip), bounds, - bounds.size, - LayoutSize::zero(), ImageRendering::Auto, AlphaType::PremultipliedAlpha, self.external_image_key.unwrap(), diff --git a/gfx/wr/examples/image_resize.rs b/gfx/wr/examples/image_resize.rs index 23b7e538f572..e71e9bc2aa86 100644 --- a/gfx/wr/examples/image_resize.rs +++ b/gfx/wr/examples/image_resize.rs @@ -55,8 +55,6 @@ impl Example for App { space_and_clip, ), bounds, - image_size, - LayoutSize::zero(), ImageRendering::Auto, AlphaType::PremultipliedAlpha, self.image_key, @@ -69,8 +67,6 @@ impl Example for App { space_and_clip, ), bounds, - image_size, - LayoutSize::zero(), ImageRendering::Pixelated, AlphaType::PremultipliedAlpha, self.image_key, diff --git a/gfx/wr/examples/texture_cache_stress.rs b/gfx/wr/examples/texture_cache_stress.rs index f2bde6294b2a..1fed7793457e 100644 --- a/gfx/wr/examples/texture_cache_stress.rs +++ b/gfx/wr/examples/texture_cache_stress.rs @@ -147,8 +147,6 @@ impl Example for App { builder.push_image( &info, bounds, - image_size, - LayoutSize::zero(), ImageRendering::Auto, AlphaType::PremultipliedAlpha, *key, @@ -165,8 +163,6 @@ impl Example for App { builder.push_image( &info, bounds, - image_size, - LayoutSize::zero(), ImageRendering::Auto, AlphaType::PremultipliedAlpha, image_key, @@ -183,8 +179,6 @@ impl Example for App { builder.push_image( &info, bounds, - image_size, - LayoutSize::zero(), ImageRendering::Auto, AlphaType::PremultipliedAlpha, swap_key, diff --git a/gfx/wr/webrender/src/display_list_flattener.rs b/gfx/wr/webrender/src/display_list_flattener.rs index dd3d36e421a2..dd5712714ab4 100644 --- a/gfx/wr/webrender/src/display_list_flattener.rs +++ b/gfx/wr/webrender/src/display_list_flattener.rs @@ -1098,6 +1098,25 @@ impl<'a> DisplayListFlattener<'a> { apply_pipeline_clip, ); + self.add_image( + clip_and_scroll, + &layout, + layout.rect.size, + LayoutSize::zero(), + None, + info.image_key, + info.image_rendering, + info.alpha_type, + info.color, + ); + } + DisplayItem::RepeatingImage(ref info) => { + let (layout, clip_and_scroll) = self.process_common_properties_with_bounds( + &info.common, + &info.bounds, + apply_pipeline_clip, + ); + self.add_image( clip_and_scroll, &layout, diff --git a/gfx/wr/webrender_api/src/display_item.rs b/gfx/wr/webrender_api/src/display_item.rs index ee79b5a3c435..7503cdff39dd 100644 --- a/gfx/wr/webrender_api/src/display_item.rs +++ b/gfx/wr/webrender_api/src/display_item.rs @@ -104,6 +104,7 @@ pub enum DisplayItem { Gradient(GradientDisplayItem), RadialGradient(RadialGradientDisplayItem), Image(ImageDisplayItem), + RepeatingImage(RepeatingImageDisplayItem), YuvImage(YuvImageDisplayItem), BackdropFilter(BackdropFilterDisplayItem), @@ -148,6 +149,7 @@ pub enum DebugDisplayItem { Gradient(GradientDisplayItem), RadialGradient(RadialGradientDisplayItem), Image(ImageDisplayItem), + RepeatingImage(RepeatingImageDisplayItem), YuvImage(YuvImageDisplayItem), BackdropFilter(BackdropFilterDisplayItem), @@ -1071,10 +1073,28 @@ pub struct IframeDisplayItem { pub ignore_missing_pipeline: bool, } -/// This describes an image or, more generally, a background-image and its tiling. -/// (A background-image repeats in a grid to fill the specified area). +/// This describes an image that fills the specified area. It stretches or shrinks +/// the image as necessary. While RepeatingImageDisplayItem could otherwise provide +/// a superset of the functionality, it has been problematic inferring the desired +/// repetition properties when snapping changes the size of the primitive. #[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)] pub struct ImageDisplayItem { + pub common: CommonItemProperties, + /// The area to tile the image over (first tile starts at origin of this rect) + // FIXME: this should ideally just be `tile_origin` here, with the clip_rect + // defining the bounds of the item. Needs non-trivial backend changes. + pub bounds: LayoutRect, + pub image_key: ImageKey, + pub image_rendering: ImageRendering, + pub alpha_type: AlphaType, + /// A hack used by gecko to color a simple bitmap font used for tofu glyphs + pub color: ColorF, +} + +/// This describes a background-image and its tiling. It repeats in a grid to fill +/// the specified area. +#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)] +pub struct RepeatingImageDisplayItem { pub common: CommonItemProperties, /// The area to tile the image over (first tile starts at origin of this rect) // FIXME: this should ideally just be `tile_origin` here, with the clip_rect @@ -1406,6 +1426,7 @@ impl DisplayItem { DisplayItem::Gradient(..) => "gradient", DisplayItem::Iframe(..) => "iframe", DisplayItem::Image(..) => "image", + DisplayItem::RepeatingImage(..) => "repeating_image", DisplayItem::Line(..) => "line", DisplayItem::PopAllShadows => "pop_all_shadows", DisplayItem::PopReferenceFrame => "pop_reference_frame", diff --git a/gfx/wr/webrender_api/src/display_list.rs b/gfx/wr/webrender_api/src/display_list.rs index e0875af5417b..2e6426a5630b 100644 --- a/gfx/wr/webrender_api/src/display_list.rs +++ b/gfx/wr/webrender_api/src/display_list.rs @@ -623,6 +623,7 @@ impl Serialize for BuiltDisplayList { Real::HitTest(v) => Debug::HitTest(v), Real::Line(v) => Debug::Line(v), Real::Image(v) => Debug::Image(v), + Real::RepeatingImage(v) => Debug::RepeatingImage(v), Real::YuvImage(v) => Debug::YuvImage(v), Real::Border(v) => Debug::Border(v), Real::BoxShadow(v) => Debug::BoxShadow(v), @@ -727,6 +728,7 @@ impl<'de> Deserialize<'de> for BuiltDisplayList { Debug::HitTest(v) => Real::HitTest(v), Debug::Line(v) => Real::Line(v), Debug::Image(v) => Real::Image(v), + Debug::RepeatingImage(v) => Real::RepeatingImage(v), Debug::YuvImage(v) => Real::YuvImage(v), Debug::Border(v) => Real::Border(v), Debug::BoxShadow(v) => Real::BoxShadow(v), @@ -1001,6 +1003,27 @@ impl DisplayListBuilder { } pub fn push_image( + &mut self, + common: &di::CommonItemProperties, + bounds: LayoutRect, + image_rendering: di::ImageRendering, + alpha_type: di::AlphaType, + key: ImageKey, + color: ColorF, + ) { + let item = di::DisplayItem::Image(di::ImageDisplayItem { + common: *common, + bounds, + image_key: key, + image_rendering, + alpha_type, + color, + }); + + self.push_item(&item); + } + + pub fn push_repeating_image( &mut self, common: &di::CommonItemProperties, bounds: LayoutRect, @@ -1011,7 +1034,7 @@ impl DisplayListBuilder { key: ImageKey, color: ColorF, ) { - let item = di::DisplayItem::Image(di::ImageDisplayItem { + let item = di::DisplayItem::RepeatingImage(di::RepeatingImageDisplayItem { common: *common, bounds, image_key: key, diff --git a/gfx/wr/wrench/reftests/performance/no-clip-mask.yaml b/gfx/wr/wrench/reftests/performance/no-clip-mask.yaml index 4cd41b177ea1..51d981e2a070 100644 --- a/gfx/wr/wrench/reftests/performance/no-clip-mask.yaml +++ b/gfx/wr/wrench/reftests/performance/no-clip-mask.yaml @@ -21,3 +21,4 @@ pipelines: bounds: [1075, -1, 12, 199] "clip-rect": [1075, -1, 12, 199] image: checkerboard(4, 8, 8) + stretch-size: 72 72 diff --git a/gfx/wr/wrench/reftests/transforms/near-plane-clip.yaml b/gfx/wr/wrench/reftests/transforms/near-plane-clip.yaml index bb12f35d1381..99cc121de713 100644 --- a/gfx/wr/wrench/reftests/transforms/near-plane-clip.yaml +++ b/gfx/wr/wrench/reftests/transforms/near-plane-clip.yaml @@ -15,3 +15,4 @@ root: - bounds: [350, 200, 260, 300] image: checkerboard(2, 16, 16) + stretch-size: 260 260 diff --git a/gfx/wr/wrench/src/rawtest.rs b/gfx/wr/wrench/src/rawtest.rs index dc3cbe55a68e..49f849002b59 100644 --- a/gfx/wr/wrench/src/rawtest.rs +++ b/gfx/wr/wrench/src/rawtest.rs @@ -163,8 +163,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info, info.clip_rect, - size2(64.0, 64.0), - size2(64.0, 64.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, img, @@ -192,8 +190,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info, info.clip_rect, - size2(1024.0, 1024.0), - size2(1024.0, 1024.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, img, @@ -218,8 +214,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info, info.clip_rect, - size2(1024.0, 1024.0), - size2(1024.0, 1024.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, img, @@ -255,7 +249,7 @@ impl<'a> RawtestHarness<'a> { let info = self.make_common_properties(rect(448.899994, 74.0, 151.000031, 56.)); // setup some malicious image size parameters - builder.push_image( + builder.push_repeating_image( &info, info.clip_rect, size2(151., 56.0), @@ -335,7 +329,7 @@ impl<'a> RawtestHarness<'a> { }; // setup some malicious image size parameters - builder.push_image( + builder.push_repeating_image( &info, info.clip_rect, image_size * 2., @@ -440,7 +434,7 @@ impl<'a> RawtestHarness<'a> { Some(100), ); - builder.push_image( + builder.push_repeating_image( &info, info.clip_rect, image_size, @@ -477,7 +471,7 @@ impl<'a> RawtestHarness<'a> { Some(100), ); - builder.push_image( + builder.push_repeating_image( &info, info.clip_rect, image_size, @@ -532,7 +526,7 @@ impl<'a> RawtestHarness<'a> { let image_size = size2(1510., 1510.); // setup some malicious image size parameters - builder.push_image( + builder.push_repeating_image( &info, info.clip_rect, image_size, @@ -558,7 +552,7 @@ impl<'a> RawtestHarness<'a> { let image_size = size2(1510., 1510.); // setup some malicious image size parameters - builder.push_image( + builder.push_repeating_image( &info, info.clip_rect, image_size, @@ -590,7 +584,7 @@ impl<'a> RawtestHarness<'a> { let image_size = size2(1510., 1510.); // setup some malicious image size parameters - builder.push_image( + builder.push_repeating_image( &info, info.clip_rect, image_size, @@ -656,8 +650,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info, info.clip_rect, - size2(200.0, 200.0), - size2(0.0, 0.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, blob_img.as_image(), @@ -680,8 +672,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info, info.clip_rect, - size2(200.0, 200.0), - size2(0.0, 0.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, blob_img.as_image(), @@ -767,8 +757,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info, info.clip_rect, - size2(200.0, 200.0), - size2(0.0, 0.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, blob_img.as_image(), @@ -777,8 +765,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info2, info2.clip_rect, - size2(200.0, 200.0), - size2(0.0, 0.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, blob_img2.as_image(), @@ -870,8 +856,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info, info.clip_rect, - size2(200.0, 200.0), - size2(0.0, 0.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, blob_img.as_image(), @@ -899,8 +883,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info, info.clip_rect, - size2(200.0, 200.0), - size2(0.0, 0.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, blob_img.as_image(), @@ -926,8 +908,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info, info.clip_rect, - size2(200.0, 200.0), - size2(0.0, 0.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, blob_img.as_image(), @@ -1126,8 +1106,6 @@ impl<'a> RawtestHarness<'a> { builder.push_image( &info, info.clip_rect, - size2(150.0, 50.0), - size2(0.0, 0.0), ImageRendering::Auto, AlphaType::PremultipliedAlpha, image, diff --git a/gfx/wr/wrench/src/yaml_frame_reader.rs b/gfx/wr/wrench/src/yaml_frame_reader.rs index acab7fca4b08..77d9aaba00b9 100644 --- a/gfx/wr/wrench/src/yaml_frame_reader.rs +++ b/gfx/wr/wrench/src/yaml_frame_reader.rs @@ -1374,10 +1374,6 @@ impl YamlFrameReader { item["bounds"] ); }; - let stretch_size = item["stretch-size"].as_size().unwrap_or(image_dims); - let tile_spacing = item["tile-spacing"] - .as_size() - .unwrap_or(LayoutSize::new(0.0, 0.0)); let rendering = match item["rendering"].as_str() { Some("auto") | None => ImageRendering::Auto, Some("crisp-edges") => ImageRendering::CrispEdges, @@ -1395,16 +1391,29 @@ impl YamlFrameReader { item ), }; - dl.push_image( - &info, - bounds, - stretch_size, - tile_spacing, - rendering, - alpha_type, - image_key, - ColorF::WHITE, - ); + let stretch_size = item["stretch-size"].as_size(); + let tile_spacing = item["tile-spacing"].as_size(); + if stretch_size.is_none() && tile_spacing.is_none() { + dl.push_image( + &info, + bounds, + rendering, + alpha_type, + image_key, + ColorF::WHITE, + ); + } else { + dl.push_repeating_image( + &info, + bounds, + stretch_size.unwrap_or(image_dims), + tile_spacing.unwrap_or(LayoutSize::zero()), + rendering, + alpha_type, + image_key, + ColorF::WHITE, + ); + } } fn handle_text( diff --git a/gfx/wr/wrench/src/yaml_frame_writer.rs b/gfx/wr/wrench/src/yaml_frame_writer.rs index 6c1c8939f579..b3f37bea6de6 100644 --- a/gfx/wr/wrench/src/yaml_frame_writer.rs +++ b/gfx/wr/wrench/src/yaml_frame_writer.rs @@ -1053,6 +1053,29 @@ impl YamlFrameWriter { } } DisplayItem::Image(item) => { + common_node(&mut v, clip_id_mapper, &item.common); + rect_node(&mut v, "bounds", &item.bounds); + if let Some(path) = self.path_for_image(item.image_key) { + path_node(&mut v, "image", &path); + } + if let Some(&CachedImage { + tiling: Some(tile_size), + .. + }) = self.images.get(&item.image_key) + { + u32_node(&mut v, "tile-size", tile_size as u32); + } + match item.image_rendering { + ImageRendering::Auto => (), + ImageRendering::CrispEdges => str_node(&mut v, "rendering", "crisp-edges"), + ImageRendering::Pixelated => str_node(&mut v, "rendering", "pixelated"), + }; + match item.alpha_type { + AlphaType::PremultipliedAlpha => str_node(&mut v, "alpha-type", "premultiplied-alpha"), + AlphaType::Alpha => str_node(&mut v, "alpha-type", "alpha"), + }; + } + DisplayItem::RepeatingImage(item) => { common_node(&mut v, clip_id_mapper, &item.common); rect_node(&mut v, "bounds", &item.bounds); if let Some(path) = self.path_for_image(item.image_key) { diff --git a/layout/painting/nsImageRenderer.cpp b/layout/painting/nsImageRenderer.cpp index 469a4890a20b..31a2c4fa7349 100644 --- a/layout/painting/nsImageRenderer.cpp +++ b/layout/painting/nsImageRenderer.cpp @@ -630,47 +630,47 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems( break; } - nsPoint firstTilePos = nsLayoutUtils::GetBackgroundFirstTilePos( - aDest.TopLeft(), aFill.TopLeft(), aRepeatSize); - LayoutDeviceRect fillRect = LayoutDeviceRect::FromAppUnits( - nsRect(firstTilePos.x, firstTilePos.y, aFill.XMost() - firstTilePos.x, - aFill.YMost() - firstTilePos.y), - appUnitsPerDevPixel); - wr::LayoutRect fill = wr::ToRoundedLayoutRect(fillRect); - wr::LayoutRect roundedDest = wr::ToLayoutRect(destRect); - // WebRender special cases situations where stretchSize == fillSize to - // infer that it shouldn't use repeat sampling. This makes sure - // we hit those special cases when not repeating. - - switch (mExtendMode) { - case ExtendMode::CLAMP: - fill = roundedDest; - stretchSize = roundedDest.size; - break; - case ExtendMode::REPEAT_Y: - fill.origin.x = roundedDest.origin.x; - fill.size.width = roundedDest.size.width; - stretchSize.width = roundedDest.size.width; - break; - case ExtendMode::REPEAT_X: - fill.origin.y = roundedDest.origin.y; - fill.size.height = roundedDest.size.height; - stretchSize.height = roundedDest.size.height; - break; - default: - break; - } - wr::LayoutRect clip = wr::ToRoundedLayoutRect( LayoutDeviceRect::FromAppUnits(aFill, appUnitsPerDevPixel)); - LayoutDeviceSize gapSize = LayoutDeviceSize::FromAppUnits( - aRepeatSize - aDest.Size(), appUnitsPerDevPixel); + if (mExtendMode == ExtendMode::CLAMP) { + // The image is not repeating. Just push as a regular image. + aBuilder.PushImage(roundedDest, clip, !aItem->BackfaceIsHidden(), + rendering, key.value()); + } else { + nsPoint firstTilePos = nsLayoutUtils::GetBackgroundFirstTilePos( + aDest.TopLeft(), aFill.TopLeft(), aRepeatSize); + LayoutDeviceRect fillRect = LayoutDeviceRect::FromAppUnits( + nsRect(firstTilePos.x, firstTilePos.y, + aFill.XMost() - firstTilePos.x, + aFill.YMost() - firstTilePos.y), + appUnitsPerDevPixel); + wr::LayoutRect fill = wr::ToRoundedLayoutRect(fillRect); - aBuilder.PushImage(fill, clip, !aItem->BackfaceIsHidden(), stretchSize, - wr::ToLayoutSize(gapSize), rendering, key.value()); + switch (mExtendMode) { + case ExtendMode::REPEAT_Y: + fill.origin.x = roundedDest.origin.x; + fill.size.width = roundedDest.size.width; + stretchSize.width = roundedDest.size.width; + break; + case ExtendMode::REPEAT_X: + fill.origin.y = roundedDest.origin.y; + fill.size.height = roundedDest.size.height; + stretchSize.height = roundedDest.size.height; + break; + default: + break; + } + + LayoutDeviceSize gapSize = LayoutDeviceSize::FromAppUnits( + aRepeatSize - aDest.Size(), appUnitsPerDevPixel); + + aBuilder.PushRepeatingImage(fill, clip, !aItem->BackfaceIsHidden(), + stretchSize, wr::ToLayoutSize(gapSize), + rendering, key.value()); + } break; } default: diff --git a/layout/xul/nsImageBoxFrame.cpp b/layout/xul/nsImageBoxFrame.cpp index da347e8fd3ad..05b6715e5fcf 100644 --- a/layout/xul/nsImageBoxFrame.cpp +++ b/layout/xul/nsImageBoxFrame.cpp @@ -442,12 +442,9 @@ ImgDrawResult nsImageBoxFrame::CreateWebRenderCommands( if (key.isNothing()) { return result; } - wr::LayoutRect fill = wr::ToLayoutRect(fillRect); - LayoutDeviceSize gapSize(0, 0); - aBuilder.PushImage(fill, fill, !BackfaceIsHidden(), - wr::ToLayoutSize(fillRect.Size()), - wr::ToLayoutSize(gapSize), rendering, key.value()); + wr::LayoutRect fill = wr::ToLayoutRect(fillRect); + aBuilder.PushImage(fill, fill, !BackfaceIsHidden(), rendering, key.value()); return result; }