Bug 1415034 - Add drop-shadow support. r=kats
☠☠ backed out by bcae439efd9c ☠ ☠
authorMorris Tseng <mtseng@mozilla.com>
Wed, 13 Dec 2017 10:53:33 -0600
changeset 396240 fd2a2e17aef386ad47cfbd2259b7dd791999d194
parent 396239 c885e730dded79619acf357346b4954ef24a79b0
child 396241 bcae439efd9ce769f1412b14d2c4ce3205117eb9
push id56955
push userncsoregi@mozilla.com
push dateWed, 13 Dec 2017 22:16:06 +0000
treeherderautoland@2d07da0b4098 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1415034
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
gfx/webrender_bindings/WebRenderTypes.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
layout/painting/nsDisplayList.cpp
layout/reftests/svg/filters/css-filter-chains/reftest.list
layout/reftests/svg/filters/css-filters/reftest.list
--- 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
@@ -9967,16 +9967,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->mRadius, appUnitsPerDevPixel),
+          NSAppUnitsToFloatPixels(shadow->mXOffset, appUnitsPerDevPixel),
+          NSAppUnitsToFloatPixels(shadow->mYOffset, 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
+fuzzy(5,13000) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&layersGPUAccelerated,35,13057) fails-if(webrender) == 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