Element with blur backdrop-filter shows edge duplication and dark edges
authordino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 22 Jun 2015 22:06:45 +0000 (22:06 +0000)
committerdino@apple.com <dino@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 22 Jun 2015 22:06:45 +0000 (22:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=146215
<rdar://problem/20367695>

Reviewed by Tim Horton.

Source/WebCore:

The input images to backdrop filters should duplicate their edge pixels
outwards, rather than using transparent pixels. This is a flag we
set on the Gaussian blur, but means we have to remember if the
FilterOperations list came from a regular filter or a backdrop filter.

Test: css3/filters/backdrop/blur-input-bounds.html

* css/CSSPropertyNames.in: New custom convertor for backdrop-filter.
* css/StyleBuilderConverter.h:
(WebCore::StyleBuilderConverter::convertBackdropFilterOperations): New convertor
that sets the backdrop flag, but is otherwise the same as a normal filter
convertor.
* page/animation/CSSPropertyAnimation.cpp:
(WebCore::blendFilterOperations): Inherit the backdrop flag if either of our
inputs has it.
* platform/graphics/ca/mac/PlatformCAFiltersMac.mm: Set the inputNormalizeEdges
key on the CAFilter if necessary.
* platform/graphics/filters/FilterOperations.cpp: Add a new flag indicating if
these operations are intended for backdrops.
(WebCore::FilterOperations::operator=):
(WebCore::FilterOperations::operator==):
* platform/graphics/filters/FilterOperations.h:
(WebCore::FilterOperations::isUsedForBackdropFilters):
(WebCore::FilterOperations::setUsedForBackdropFilters):

LayoutTests:

Add a pixel test to show that the input images to backdrop filters should duplicate their
edge pixels. Unfortunately this is not reproducible with normal filters, so it
can't be a reference test.

* css3/filters/backdrop/blur-input-bounds.html: Added.
* platform/mac/css3/filters/backdrop/blur-input-bounds-expected.png: Added.
* platform/mac/css3/filters/backdrop/blur-input-bounds-expected.txt: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185846 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/css3/filters/backdrop/blur-input-bounds.html [new file with mode: 0644]
LayoutTests/platform/mac/css3/filters/backdrop/blur-input-bounds-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/css3/filters/backdrop/blur-input-bounds-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSPropertyNames.in
Source/WebCore/css/StyleBuilderConverter.h
Source/WebCore/page/animation/CSSPropertyAnimation.cpp
Source/WebCore/platform/graphics/ca/mac/PlatformCAFiltersMac.mm
Source/WebCore/platform/graphics/filters/FilterOperations.cpp
Source/WebCore/platform/graphics/filters/FilterOperations.h

index 9458504..43fe711 100644 (file)
@@ -1,3 +1,19 @@
+2015-06-22  Dean Jackson  <dino@apple.com>
+
+        Element with blur backdrop-filter shows edge duplication and dark edges
+        https://bugs.webkit.org/show_bug.cgi?id=146215
+        <rdar://problem/20367695>
+
+        Reviewed by Tim Horton.
+
+        Add a pixel test to show that the input images to backdrop filters should duplicate their
+        edge pixels. Unfortunately this is not reproducible with normal filters, so it
+        can't be a reference test.
+
+        * css3/filters/backdrop/blur-input-bounds.html: Added.
+        * platform/mac/css3/filters/backdrop/blur-input-bounds-expected.png: Added.
+        * platform/mac/css3/filters/backdrop/blur-input-bounds-expected.txt: Added.
+
 2015-06-22  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [iOS] Arabic text styled with Georgia is rendered as boxes
diff --git a/LayoutTests/css3/filters/backdrop/blur-input-bounds.html b/LayoutTests/css3/filters/backdrop/blur-input-bounds.html
new file mode 100644 (file)
index 0000000..794204a
--- /dev/null
@@ -0,0 +1,32 @@
+<style>
+div {
+    display: inline-block;
+    position: relative;
+    margin: 10px;
+    width: 160px;
+    height: 80px;
+}
+
+img {
+    position: absolute;
+    top: 0;
+    left: 0;
+    margin: 0;
+    padding: 0;
+}
+
+p {
+    position: absolute;
+    top: 10px;
+    left: 20px;
+    width: 120px;
+    height: 60px;
+    margin: 0;
+    padding: 0;
+}
+
+</style>
+<div>
+    <img src="../resources/reference.png">
+    <p style="-webkit-backdrop-filter: blur(10px)"></p>
+</div>
diff --git a/LayoutTests/platform/mac/css3/filters/backdrop/blur-input-bounds-expected.png b/LayoutTests/platform/mac/css3/filters/backdrop/blur-input-bounds-expected.png
new file mode 100644 (file)
index 0000000..18e075e
Binary files /dev/null and b/LayoutTests/platform/mac/css3/filters/backdrop/blur-input-bounds-expected.png differ
diff --git a/LayoutTests/platform/mac/css3/filters/backdrop/blur-input-bounds-expected.txt b/LayoutTests/platform/mac/css3/filters/backdrop/blur-input-bounds-expected.txt
new file mode 100644 (file)
index 0000000..de7fee1
--- /dev/null
@@ -0,0 +1,12 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (0,0) size 0x0
+layer at (18,18) size 160x80
+  RenderBlock (relative positioned) {DIV} at (10,10) size 160x80
+layer at (18,18) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (38,28) size 120x60
+  RenderBlock (positioned) {P} at (20,10) size 120x60
index d202afc..4cfc06e 100644 (file)
@@ -1,3 +1,36 @@
+2015-06-22  Dean Jackson  <dino@apple.com>
+
+        Element with blur backdrop-filter shows edge duplication and dark edges
+        https://bugs.webkit.org/show_bug.cgi?id=146215
+        <rdar://problem/20367695>
+
+        Reviewed by Tim Horton.
+
+        The input images to backdrop filters should duplicate their edge pixels
+        outwards, rather than using transparent pixels. This is a flag we
+        set on the Gaussian blur, but means we have to remember if the
+        FilterOperations list came from a regular filter or a backdrop filter.
+
+        Test: css3/filters/backdrop/blur-input-bounds.html
+
+        * css/CSSPropertyNames.in: New custom convertor for backdrop-filter.
+        * css/StyleBuilderConverter.h:
+        (WebCore::StyleBuilderConverter::convertBackdropFilterOperations): New convertor
+        that sets the backdrop flag, but is otherwise the same as a normal filter
+        convertor.
+        * page/animation/CSSPropertyAnimation.cpp:
+        (WebCore::blendFilterOperations): Inherit the backdrop flag if either of our
+        inputs has it.
+        * platform/graphics/ca/mac/PlatformCAFiltersMac.mm: Set the inputNormalizeEdges
+        key on the CAFilter if necessary.
+        * platform/graphics/filters/FilterOperations.cpp: Add a new flag indicating if
+        these operations are intended for backdrops.
+        (WebCore::FilterOperations::operator=):
+        (WebCore::FilterOperations::operator==):
+        * platform/graphics/filters/FilterOperations.h:
+        (WebCore::FilterOperations::isUsedForBackdropFilters):
+        (WebCore::FilterOperations::setUsedForBackdropFilters):
+
 2015-06-22  Tim Horton  <timothy_horton@apple.com>
 
         [TextIndicator] Text shifts one pixel to the left when I force click to bring up Lookup in Mail messages
index ef94364..f012fcc 100644 (file)
@@ -476,7 +476,7 @@ flex-wrap
 justify-content [Initial=initialContentAlignment, Converter=ContentAlignmentData]
 -webkit-justify-content = justify-content
 #if defined(ENABLE_FILTERS_LEVEL_2) && ENABLE_FILTERS_LEVEL_2
--webkit-backdrop-filter [ConditionalConverter=FilterOperations]
+-webkit-backdrop-filter [ConditionalConverter=BackdropFilterOperations]
 #endif
 justify-self [Initial=initialSelfAlignment, Converter=SelfOrDefaultAlignmentData]
 -webkit-font-size-delta [SkipBuilder]
index 417a401..a9012fa 100644 (file)
@@ -104,6 +104,9 @@ public:
     static Optional<float> convertPerspective(StyleResolver&, CSSValue&);
     static Optional<Length> convertMarqueeIncrement(StyleResolver&, CSSValue&);
     static Optional<FilterOperations> convertFilterOperations(StyleResolver&, CSSValue&);
+#if ENABLE(FILTERS_LEVEL_2)
+    static Optional<FilterOperations> convertBackdropFilterOperations(StyleResolver&, CSSValue&);
+#endif
     static Vector<RefPtr<MaskImageOperation>> convertMaskImageOperations(StyleResolver&, CSSValue&);
 #if PLATFORM(IOS)
     static bool convertTouchCallout(StyleResolver&, CSSValue&);
@@ -1005,6 +1008,18 @@ inline Optional<FilterOperations> StyleBuilderConverter::convertFilterOperations
     return Nullopt;
 }
 
+#if ENABLE(FILTERS_LEVEL_2)
+inline Optional<FilterOperations> StyleBuilderConverter::convertBackdropFilterOperations(StyleResolver& styleResolver, CSSValue& value)
+{
+    FilterOperations operations;
+    if (styleResolver.createFilterOperations(value, operations)) {
+        operations.setUsedForBackdropFilters(true);
+        return operations;
+    }
+    return Nullopt;
+}
+#endif
+
 static inline WebKitCSSResourceValue* maskImageValueFromIterator(CSSValueList& maskImagesList, CSSValueList::iterator it)
 {
     // May also be a CSSInitialValue.
index 192bcef..ce09e0a 100644 (file)
@@ -192,6 +192,10 @@ static inline FilterOperations blendFilterOperations(const AnimationBase* anim,
                 result.operations().append(fromOp ? fromOp : identityOp);
         }
     }
+#if ENABLE(FILTERS_LEVEL_2)
+    result.setUsedForBackdropFilters(from.isUsedForBackdropFilters() || to.isUsedForBackdropFilters());
+#endif
+
     return result;
 }
 
index 7981517..a8685e9 100644 (file)
@@ -161,6 +161,10 @@ void PlatformCAFilters::setFiltersOnLayer(PlatformLayer* layer, const FilterOper
             const auto& blurOperation = downcast<BlurFilterOperation>(filterOperation);
             CAFilter *filter = [CAFilter filterWithType:kCAFilterGaussianBlur];
             [filter setValue:[NSNumber numberWithFloat:floatValueForLength(blurOperation.stdDeviation(), 0)] forKey:@"inputRadius"];
+#if ENABLE(FILTERS_LEVEL_2)
+            if (filters.isUsedForBackdropFilters())
+                [filter setValue:[NSNumber numberWithBool:YES] forKey:@"inputNormalizeEdges"];
+#endif
             [filter setName:filterName];
             [array.get() addObject:filter];
             break;
index e1505dd..dba7523 100644 (file)
@@ -51,6 +51,9 @@ FilterOperations::FilterOperations()
 FilterOperations& FilterOperations::operator=(const FilterOperations& other)
 {
     m_operations = other.m_operations;
+#if ENABLE(FILTERS_LEVEL_2)
+    m_usedForBackdropFilters = other.m_usedForBackdropFilters;
+#endif
     return *this;
 }
 
@@ -58,7 +61,12 @@ bool FilterOperations::operator==(const FilterOperations& o) const
 {
     if (m_operations.size() != o.m_operations.size())
         return false;
-        
+
+#if ENABLE(FILTERS_LEVEL_2)
+    if (m_usedForBackdropFilters != o.m_usedForBackdropFilters)
+        return false;
+#endif
+
     unsigned s = m_operations.size();
     for (unsigned i = 0; i < s; i++) {
         if (*m_operations[i] != *o.m_operations[i])
index 424660a..3894494 100644 (file)
@@ -42,7 +42,7 @@ public:
     FilterOperations(const FilterOperations& other) { *this = other; }
     
     WEBCORE_EXPORT FilterOperations& operator=(const FilterOperations&);
-    
+
     bool operator==(const FilterOperations&) const;
     bool operator!=(const FilterOperations& o) const
     {
@@ -70,8 +70,17 @@ public:
     bool hasFilterThatMovesPixels() const;
 
     bool hasReferenceFilter() const;
+
+#if ENABLE(FILTERS_LEVEL_2)
+    bool isUsedForBackdropFilters() const { return m_usedForBackdropFilters; }
+    void setUsedForBackdropFilters(bool usedForBackdrop) { m_usedForBackdropFilters = usedForBackdrop; }
+#endif
+
 private:
     Vector<RefPtr<FilterOperation>> m_operations;
+#if ENABLE(FILTERS_LEVEL_2)
+    bool m_usedForBackdropFilters { false };
+#endif
 };
 
 } // namespace WebCore