Title: [115397] trunk/Source
Revision
115397
Author
[email protected]
Date
2012-04-26 19:17:03 -0700 (Thu, 26 Apr 2012)

Log Message

[chromium] Some background filters require inflating damage on the surface behind them
https://bugs.webkit.org/show_bug.cgi?id=84479

Reviewed by Adrienne Walker.

Source/WebCore:

A layer with a background blur will expand the damage from pixels in the
surface below it. We extend the damage tracker to expand damage in a
surface below such layers.

Unit test: CCDamageTrackerTest.verifyDamageForBackgroundBlurredChild

* platform/graphics/chromium/cc/CCDamageTracker.cpp:
(WebCore::expandPixelOutsetsWithFilters):
(WebCore):
(WebCore::expandDamageRectInsideRectWithFilters):
(WebCore::expandDamageRectWithFilters):
(WebCore::CCDamageTracker::updateDamageTrackingState):
(WebCore::CCDamageTracker::trackDamageFromActiveLayers):
* platform/graphics/chromium/cc/CCDamageTracker.h:
(CCDamageTracker):

Source/WebKit/chromium:

* tests/CCDamageTrackerTest.cpp:
(WebKitTests::TEST_F):
(WebKitTests):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (115396 => 115397)


--- trunk/Source/WebCore/ChangeLog	2012-04-27 01:40:10 UTC (rev 115396)
+++ trunk/Source/WebCore/ChangeLog	2012-04-27 02:17:03 UTC (rev 115397)
@@ -1,3 +1,26 @@
+2012-04-26  Dana Jansens  <[email protected]>
+
+        [chromium] Some background filters require inflating damage on the surface behind them
+        https://bugs.webkit.org/show_bug.cgi?id=84479
+
+        Reviewed by Adrienne Walker.
+
+        A layer with a background blur will expand the damage from pixels in the
+        surface below it. We extend the damage tracker to expand damage in a
+        surface below such layers.
+
+        Unit test: CCDamageTrackerTest.verifyDamageForBackgroundBlurredChild
+
+        * platform/graphics/chromium/cc/CCDamageTracker.cpp:
+        (WebCore::expandPixelOutsetsWithFilters):
+        (WebCore):
+        (WebCore::expandDamageRectInsideRectWithFilters):
+        (WebCore::expandDamageRectWithFilters):
+        (WebCore::CCDamageTracker::updateDamageTrackingState):
+        (WebCore::CCDamageTracker::trackDamageFromActiveLayers):
+        * platform/graphics/chromium/cc/CCDamageTracker.h:
+        (CCDamageTracker):
+
 2012-04-26  Simon Fraser  <[email protected]>
 
         Improve compositing logging output

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp (115396 => 115397)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp	2012-04-27 01:40:10 UTC (rev 115396)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp	2012-04-27 02:17:03 UTC (rev 115397)
@@ -58,6 +58,23 @@
 {
 }
 
+static inline void expandDamageRectWithFilters(FloatRect& damageRect, const FilterOperations& filters)
+{
+    int top, right, bottom, left;
+    filters.getOutsets(top, right, bottom, left);
+    damageRect.move(-left, -top);
+    damageRect.expand(left + right, top + bottom);
+}
+
+static inline void expandDamageRectInsideRectWithFilters(FloatRect& damageRect, const FloatRect& filterRect, const FilterOperations& filters)
+{
+    FloatRect expandedDamageRect = damageRect;
+    expandDamageRectWithFilters(expandedDamageRect, filters);
+    expandedDamageRect.intersect(filterRect);
+
+    damageRect.unite(expandedDamageRect);
+}
+
 void CCDamageTracker::updateDamageTrackingState(const Vector<CCLayerImpl*>& layerList, int targetSurfaceLayerID, bool targetSurfacePropertyChangedOnlyFromDescendant, const IntRect& targetSurfaceContentRect, CCLayerImpl* targetSurfaceMaskLayer, const FilterOperations& filters)
 {
     //
@@ -139,7 +156,8 @@
         m_currentDamageRect.uniteIfNonZero(damageFromSurfaceMask);
         m_currentDamageRect.uniteIfNonZero(damageFromLeftoverRects);
 
-        expandDamageRectWithForegroundFilters(filters);
+        if (filters.hasFilterThatMovesPixels())
+            expandDamageRectWithFilters(m_currentDamageRect, filters);
     }
 
     // The next history map becomes the current map for the next frame.
@@ -166,6 +184,7 @@
     FloatRect damageRect = FloatRect();
 
     for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
+        // Visit layers in back-to-front order.
         CCLayerImpl* layer = layerList[layerIndex];
 
         if (CCLayerTreeHostCommon::renderSurfaceContributesToTarget<CCLayerImpl>(layer, targetSurfaceLayerID))
@@ -269,6 +288,11 @@
     FloatRect surfaceRectInTargetSpace = renderSurface->drawableContentRect(); // already includes replica if it exists.
     saveRectForNextFrame(layer->id(), surfaceRectInTargetSpace);
 
+    // If the layer has a background filter, this may cause pixels in our surface to be expanded, so we will need to expand any damage
+    // that exists below this layer by that amount.
+    if (layer->backgroundFilters().hasFilterThatMovesPixels())
+        expandDamageRectInsideRectWithFilters(targetDamageRect, surfaceRectInTargetSpace, layer->backgroundFilters());
+
     FloatRect damageRectInLocalSpace;
     if (surfaceIsNew || renderSurface->surfacePropertyChanged()) {
         // The entire surface contributes damage.
@@ -311,17 +335,6 @@
     }
 }
 
-void CCDamageTracker::expandDamageRectWithForegroundFilters(const FilterOperations& filters)
-{
-    // Filters can spread damage around in the surface.
-    if (filters.hasFilterThatMovesPixels()) {
-        int top, right, bottom, left;
-        filters.getOutsets(top, right, bottom, left);
-        m_currentDamageRect.move(-left, -top);
-        m_currentDamageRect.expand(left + right, top + bottom);
-    }
-}
-
 } // namespace WebCore
 
 #endif // USE(ACCELERATED_COMPOSITING)

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.h (115396 => 115397)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.h	2012-04-27 01:40:10 UTC (rev 115396)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.h	2012-04-27 02:17:03 UTC (rev 115397)
@@ -62,8 +62,6 @@
     void extendDamageForLayer(CCLayerImpl*, FloatRect& targetDamageRect);
     void extendDamageForRenderSurface(CCLayerImpl*, FloatRect& targetDamageRect);
 
-    void expandDamageRectWithForegroundFilters(const FilterOperations&);
-
     // To correctly track exposed regions, two hashtables of rects are maintained.
     // The "current" map is used to compute exposed regions of the current frame, while
     // the "next" map is used to collect layer rects that are used in the next frame.

Modified: trunk/Source/WebKit/chromium/ChangeLog (115396 => 115397)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-04-27 01:40:10 UTC (rev 115396)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-04-27 02:17:03 UTC (rev 115397)
@@ -1,3 +1,14 @@
+2012-04-26  Dana Jansens  <[email protected]>
+
+        [chromium] Some background filters require inflating damage on the surface behind them
+        https://bugs.webkit.org/show_bug.cgi?id=84479
+
+        Reviewed by Adrienne Walker.
+
+        * tests/CCDamageTrackerTest.cpp:
+        (WebKitTests::TEST_F):
+        (WebKitTests):
+
 2012-04-26  Aaron Colwell  <[email protected]>
 
         Cleanup WebMediaPlayer enum values that didn't match Chromium style guidelines

Modified: trunk/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp (115396 => 115397)


--- trunk/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp	2012-04-27 01:40:10 UTC (rev 115396)
+++ trunk/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp	2012-04-27 02:17:03 UTC (rev 115397)
@@ -365,7 +365,7 @@
     CCLayerImpl* child = root->children()[0].get();
 
     FilterOperations filters;
-    filters.operations().append(BlurFilterOperation::create(Length(5, WebCore::Percent), FilterOperation::BLUR));
+    filters.operations().append(BlurFilterOperation::create(Length(5, WebCore::Fixed), FilterOperation::BLUR));
     int outsetTop, outsetRight, outsetBottom, outsetLeft;
     filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
     root->setFilters(filters);
@@ -385,6 +385,77 @@
     EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
 }
 
+TEST_F(CCDamageTrackerTest, verifyDamageForBackgroundBlurredChild)
+{
+    OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithTwoSurfaces();
+    CCLayerImpl* child1 = root->children()[0].get();
+    CCLayerImpl* child2 = root->children()[1].get();
+
+    FilterOperations filters;
+    filters.operations().append(BlurFilterOperation::create(Length(2, WebCore::Fixed), FilterOperation::BLUR));
+    int outsetTop, outsetRight, outsetBottom, outsetLeft;
+    filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
+    child1->setBackgroundFilters(filters);
+
+    // Setting the filter will damage the whole surface.
+    emulateDrawingOneFrame(root.get());
+
+    // CASE 1: Setting the update rect should cause the corresponding damage to
+    // the surface, blurred based on the size of the child's background blur
+    // filter.
+    root->setUpdateRect(FloatRect(297, 297, 2, 2));
+
+    emulateDrawingOneFrame(root.get());
+
+    FloatRect rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+    // Damage position on the surface should be a composition of the damage on the root and on child2.
+    // Damage on the root should be: position of updateRect (297, 297), but expanded by the blur outsets.
+    FloatRect expectedDamageRect = FloatRect(297, 297, 2, 2);
+    expectedDamageRect.move(-outsetLeft, -outsetTop);
+    expectedDamageRect.expand(outsetLeft + outsetRight, outsetTop + outsetBottom);
+    EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+
+    // CASE 2: Setting the update rect should cause the corresponding damage to
+    // the surface, blurred based on the size of the child's background blur
+    // filter. Since the damage extends to the right/bottom outside of the
+    // blurred layer, only the left/top should end up expanded.
+    root->setUpdateRect(FloatRect(297, 297, 30, 30));
+
+    emulateDrawingOneFrame(root.get());
+
+    rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+    // Damage position on the surface should be a composition of the damage on the root and on child2.
+    // Damage on the root should be: position of updateRect (297, 297), but expanded on the left/top
+    // by the blur outsets.
+    expectedDamageRect = FloatRect(297, 297, 30, 30);
+    expectedDamageRect.move(-outsetLeft, -outsetTop);
+    expectedDamageRect.expand(outsetLeft, outsetTop);
+    EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+
+    // CASE 3: Setting this update rect outside the contentBounds of the blurred
+    // child1 will not cause it to be expanded.
+    root->setUpdateRect(FloatRect(30, 30, 2, 2));
+
+    emulateDrawingOneFrame(root.get());
+
+    rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+    // Damage on the root should be: position of updateRect (30, 30), not
+    // expanded.
+    expectedDamageRect = FloatRect(30, 30, 2, 2);
+    EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+
+    // CASE 4: Setting the update rect on child2, which is above child1, will
+    // not get blurred by child1, so it does not need to get expanded.
+    child2->setUpdateRect(FloatRect(0, 0, 1, 1));
+
+    emulateDrawingOneFrame(root.get());
+
+    rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+    // Damage on child2 should be: position of updateRect offset by the child's position (11, 11), and not expanded by anything.
+    expectedDamageRect = FloatRect(11, 11, 1, 1);
+    EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+}
+
 TEST_F(CCDamageTrackerTest, verifyDamageForAddingAndRemovingLayer)
 {
     OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithOneSurface();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to