Bug 1415034 - Add drop-shadow support. r=kats
The long-chain.html failure is tracking by
https://github.com/servo/webrender/issues/2197
MozReview-Commit-ID: FECidSvTQrY
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -725,16 +725,18 @@ static inline wr::WrFilterOpType ToWrFil
case NS_STYLE_FILTER_INVERT:
return wr::WrFilterOpType::Invert;
case NS_STYLE_FILTER_OPACITY:
return wr::WrFilterOpType::Opacity;
case NS_STYLE_FILTER_SATURATE:
return wr::WrFilterOpType::Saturate;
case NS_STYLE_FILTER_SEPIA:
return wr::WrFilterOpType::Sepia;
+ case NS_STYLE_FILTER_DROP_SHADOW:
+ return wr::WrFilterOpType::DropShadow;
}
MOZ_ASSERT_UNREACHABLE("Tried to convert unknown filter type.");
return wr::WrFilterOpType::Grayscale;
}
// Corresponds to an "internal" webrender clip id. That is, a
// ClipId::Clip(x,pipeline_id) maps to a WrClipId{x}. We use a struct wrapper
// instead of a typedef so that this is a distinct type from FrameMetrics::ViewID
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -354,23 +354,26 @@ pub enum WrFilterOpType {
Brightness = 1,
Contrast = 2,
Grayscale = 3,
HueRotate = 4,
Invert = 5,
Opacity = 6,
Saturate = 7,
Sepia = 8,
+ DropShadow = 9,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct WrFilterOp {
filter_type: WrFilterOpType,
- argument: c_float,
+ argument: c_float, // holds radius for DropShadow; value for other filters
+ offset: LayoutVector2D, // only used for DropShadow
+ color: ColorF, // only used for DropShadow
}
/// cbindgen:derive-eq=false
#[repr(C)]
#[derive(Debug)]
pub struct WrTransformProperty {
pub id: u64,
pub transform: LayoutTransform,
@@ -1288,16 +1291,19 @@ pub extern "C" fn wr_dp_push_stacking_co
WrFilterOpType::Brightness => FilterOp::Brightness(c_filter.argument),
WrFilterOpType::Contrast => FilterOp::Contrast(c_filter.argument),
WrFilterOpType::Grayscale => FilterOp::Grayscale(c_filter.argument),
WrFilterOpType::HueRotate => FilterOp::HueRotate(c_filter.argument),
WrFilterOpType::Invert => FilterOp::Invert(c_filter.argument),
WrFilterOpType::Opacity => FilterOp::Opacity(PropertyBinding::Value(c_filter.argument), c_filter.argument),
WrFilterOpType::Saturate => FilterOp::Saturate(c_filter.argument),
WrFilterOpType::Sepia => FilterOp::Sepia(c_filter.argument),
+ WrFilterOpType::DropShadow => FilterOp::DropShadow(c_filter.offset,
+ c_filter.argument,
+ c_filter.color),
}
}).collect();
let opacity_ref = unsafe { opacity.as_ref() };
if let Some(opacity) = opacity_ref {
if *opacity < 1.0 {
filters.push(FilterOp::Opacity(PropertyBinding::Value(*opacity), *opacity));
}
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -220,16 +220,17 @@ enum class WrFilterOpType : uint32_t {
Brightness = 1,
Contrast = 2,
Grayscale = 3,
HueRotate = 4,
Invert = 5,
Opacity = 6,
Saturate = 7,
Sepia = 8,
+ DropShadow = 9,
Sentinel /* this must be last for serialization purposes. */
};
enum class YuvColorSpace : uint32_t {
Rec601 = 0,
Rec709 = 1,
@@ -686,20 +687,24 @@ struct WrAnimationProperty {
return effect_type == aOther.effect_type &&
id == aOther.id;
}
};
struct WrFilterOp {
WrFilterOpType filter_type;
float argument;
+ LayoutVector2D offset;
+ ColorF color;
bool operator==(const WrFilterOp& aOther) const {
return filter_type == aOther.filter_type &&
- argument == aOther.argument;
+ argument == aOther.argument &&
+ offset == aOther.offset &&
+ color == aOther.color;
}
};
struct FontInstanceKey {
IdNamespace mNamespace;
uint32_t mHandle;
bool operator==(const FontInstanceKey& aOther) const {
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -9966,16 +9966,44 @@ nsDisplayFilter::CreateWebRenderCommands
ClampStdDeviation(
NSAppUnitsToFloatPixels(
filter.GetFilterParameter().GetCoordValue(),
appUnitsPerDevPixel)),
};
wrFilters.AppendElement(filterOp);
break;
}
+ case NS_STYLE_FILTER_DROP_SHADOW: {
+ float appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
+ nsCSSShadowArray* shadows = filter.GetDropShadow();
+ if (!shadows || shadows->Length() != 1) {
+ NS_NOTREACHED("Exactly one drop shadow should have been parsed.");
+ return false;
+ }
+
+ nsCSSShadowItem* shadow = shadows->ShadowAt(0);
+ nscolor color = shadow->mColor;
+ if (!shadow->mHasColor) {
+ color = mFrame->StyleColor()->mColor;
+ }
+
+ mozilla::wr::WrFilterOp filterOp = {
+ wr::ToWrFilterOpType(filter.GetType()),
+ NSAppUnitsToFloatPixels(shadow->mXOffset, appUnitsPerDevPixel),
+ NSAppUnitsToFloatPixels(shadow->mYOffset, appUnitsPerDevPixel),
+ NSAppUnitsToFloatPixels(shadow->mRadius, appUnitsPerDevPixel),
+ NS_GET_R(color) / 255.0f,
+ NS_GET_G(color) / 255.0f,
+ NS_GET_B(color) / 255.0f,
+ NS_GET_A(color) / 255.0f,
+ };
+
+ wrFilters.AppendElement(filterOp);
+ break;
+ }
default:
return false;
}
}
float opacity = mFrame->StyleEffects()->mOpacity;
StackingContextHelper sc(aSc, aBuilder, wrFilters, nullptr, 0, opacity != 1.0f && mHandleOpacity ? &opacity : nullptr);
--- a/layout/reftests/svg/filters/css-filter-chains/reftest.list
+++ b/layout/reftests/svg/filters/css-filter-chains/reftest.list
@@ -1,9 +1,9 @@
# These tests verify that CSS filter chains behave properly.
# e.g. filter: blur(3px) grayscale(0.5) invert(0.2);
default-preferences pref(layout.css.filters.enabled,true)
# Some platforms render this complex filter chain a little differently, and that's ok.
-fuzzy(5,13000) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&layersGPUAccelerated,35,13057) == long-chain.html long-chain-ref.html # Win10: Bug 1258241
+fails-if(webrender) fuzzy(5,13000) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&layersGPUAccelerated,35,13057) == long-chain.html long-chain-ref.html # Win10: Bug 1258241
== moz-element.html moz-element-ref.html
fuzzy-if(webrender,15-15,8262-8262) == same-filter.html same-filter-ref.html
--- a/layout/reftests/svg/filters/css-filters/reftest.list
+++ b/layout/reftests/svg/filters/css-filters/reftest.list
@@ -21,19 +21,19 @@ fuzzy-if(webrender,6-6,21308-21308) == b
== brightness-zero.html brightness-zero-ref.html
== containing-block-1.html containing-block-1-ref.html
== contrast.html contrast-ref.html
== contrast-extreme.html contrast-extreme-ref.html
== contrast-one.html contrast-one-ref.html
== contrast-percent.html contrast-percent-ref.html
== contrast-reduce.html contrast-reduce-ref.html
== contrast-zero.html contrast-zero-ref.html
-== drop-shadow.html drop-shadow-ref.html
-== drop-shadow-default-color.html drop-shadow-default-color-ref.html
-== drop-shadow-negative-offset.html drop-shadow-negative-offset-ref.html
+fuzzy-if(webrender,9-9,2625-2625) == drop-shadow.html drop-shadow-ref.html
+fuzzy-if(webrender,9-9,2625-2625) == drop-shadow-default-color.html drop-shadow-default-color-ref.html
+fuzzy-if(webrender,9-9,2625-2625) == drop-shadow-negative-offset.html drop-shadow-negative-offset-ref.html
== filter-on-huge-bbox.html pass.svg
== filter-on-outer-svg.html pass.svg
fuzzy-if(webrender,1,10000) fuzzy-if(d2d,1,10000) == grayscale.html grayscale-ref.html
fuzzy-if(webrender,1,10000) fuzzy-if(d2d,1,10000) == grayscale-one.html grayscale-one-ref.html
fuzzy-if(webrender,1,10000) fuzzy-if(d2d,1,10000) fails-if(stylo&&webrender) == grayscale-over-one.html grayscale-over-one-ref.html
fuzzy-if(webrender,1,10000) fuzzy-if(d2d,1,10000) == grayscale-percent.html grayscale-percent-ref.html
fuzzy-if(webrender,1,10000) == grayscale-zero.html grayscale-zero-ref.html
== hue-rotate.html hue-rotate-ref.html