Changeset 117981 in webkit


Ignore:
Timestamp:
May 22, 2012 9:10:09 AM (12 years ago)
Author:
danakj@chromium.org
Message:

[chromium] Expand damage from the background-blurred layer to ensure readback is only including pixels below that layer
https://bugs.webkit.org/show_bug.cgi?id=86884

Reviewed by Adrienne Walker.

Source/WebCore:

Consider layers in back-to-front order A, B, and C, where layer B has
a blur background filter applied, and C exactly covers A. When B does
its readback to perform its blur, it should include the pixels of A
not C. With partial swap, if B is damaged, that damaged area will read
pixels from outside of the damage rect. Those pixels should use the
contents of A, not C, so we must expand the damage to ensure we redraw
all pixels that are going to be included in the blur for the current
frame.

Also, when a layer below B has damage outside the contentBounds of B
but within its blur radius, then that damage will be blurred inside B,
so expand all damage within B's blurred contentBounds.

Unit test: CCDamageTrackerTest.verifyDamageForBackgroundBlurredChild

  • platform/graphics/chromium/cc/CCDamageTracker.cpp:

(WebCore::expandRectWithFilters):
(WebCore::expandDamageRectInsideRectWithFilters):
(WebCore::CCDamageTracker::updateDamageTrackingState):
(WebCore::CCDamageTracker::extendDamageForRenderSurface):

Source/WebKit/chromium:

  • tests/CCDamageTrackerTest.cpp:

(WebKitTests::TEST_F):

Location:
trunk/Source
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r117980 r117981  
     12012-05-22  Dana Jansens  <danakj@chromium.org>
     2
     3        [chromium] Expand damage from the background-blurred layer to ensure readback is only including pixels below that layer
     4        https://bugs.webkit.org/show_bug.cgi?id=86884
     5
     6        Reviewed by Adrienne Walker.
     7
     8        Consider layers in back-to-front order A, B, and C, where layer B has
     9        a blur background filter applied, and C exactly covers A. When B does
     10        its readback to perform its blur, it should include the pixels of A
     11        not C. With partial swap, if B is damaged, that damaged area will read
     12        pixels from outside of the damage rect. Those pixels should use the
     13        contents of A, not C, so we must expand the damage to ensure we redraw
     14        all pixels that are going to be included in the blur for the current
     15        frame.
     16
     17        Also, when a layer below B has damage outside the contentBounds of B
     18        but within its blur radius, then that damage will be blurred inside B,
     19        so expand all damage within B's blurred contentBounds.
     20
     21        Unit test: CCDamageTrackerTest.verifyDamageForBackgroundBlurredChild
     22
     23        * platform/graphics/chromium/cc/CCDamageTracker.cpp:
     24        (WebCore::expandRectWithFilters):
     25        (WebCore::expandDamageRectInsideRectWithFilters):
     26        (WebCore::CCDamageTracker::updateDamageTrackingState):
     27        (WebCore::CCDamageTracker::extendDamageForRenderSurface):
     28
    1292012-05-22  Mihnea Ovidenie  <mihnea@adobe.com>
    230
  • trunk/Source/WebCore/platform/graphics/chromium/cc/CCDamageTracker.cpp

    r117864 r117981  
    5959}
    6060
    61 static inline void expandDamageRectWithFilters(FloatRect& damageRect, const WebKit::WebFilterOperations& filters)
     61static inline void expandRectWithFilters(FloatRect& rect, const WebKit::WebFilterOperations& filters)
    6262{
    6363    int top, right, bottom, left;
    6464    filters.getOutsets(top, right, bottom, left);
    65     damageRect.move(-left, -top);
    66     damageRect.expand(left + right, top + bottom);
    67 }
    68 
    69 static inline void expandDamageRectInsideRectWithFilters(FloatRect& damageRect, const FloatRect& filterRect, const WebKit::WebFilterOperations& filters)
     65    rect.move(-left, -top);
     66    rect.expand(left + right, top + bottom);
     67}
     68
     69static inline void expandDamageRectInsideRectWithFilters(FloatRect& damageRect, const FloatRect& preFilterRect, const WebKit::WebFilterOperations& filters)
    7070{
    7171    FloatRect expandedDamageRect = damageRect;
    72     expandDamageRectWithFilters(expandedDamageRect, filters);
     72    expandRectWithFilters(expandedDamageRect, filters);
     73    FloatRect filterRect = preFilterRect;
     74    expandRectWithFilters(filterRect, filters);
     75
    7376    expandedDamageRect.intersect(filterRect);
    74 
    7577    damageRect.unite(expandedDamageRect);
    7678}
     
    158160
    159161        if (filters.hasFilterThatMovesPixels())
    160             expandDamageRectWithFilters(m_currentDamageRect, filters);
     162            expandRectWithFilters(m_currentDamageRect, filters);
    161163    }
    162164
     
    289291    saveRectForNextFrame(layer->id(), surfaceRectInTargetSpace);
    290292
    291     // 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
    292     // that exists below this layer by that amount.
    293     if (layer->backgroundFilters().hasFilterThatMovesPixels())
    294         expandDamageRectInsideRectWithFilters(targetDamageRect, surfaceRectInTargetSpace, layer->backgroundFilters());
    295 
    296293    FloatRect damageRectInLocalSpace;
    297294    if (surfaceIsNew || renderSurface->surfacePropertyChanged()) {
     
    334331            targetDamageRect.uniteIfNonZero(replicaMaskLayerRect);
    335332    }
     333
     334    // 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
     335    // at or below this layer. We expand the damage from this layer too, as we need to readback those pixels from the surface with only
     336    // the contents of layers below this one in them. This means we need to redraw any pixels in the surface being used for the blur in
     337    // this layer this frame.
     338    if (layer->backgroundFilters().hasFilterThatMovesPixels())
     339        expandDamageRectInsideRectWithFilters(targetDamageRect, surfaceRectInTargetSpace, layer->backgroundFilters());
    336340}
    337341
  • trunk/Source/WebKit/chromium/ChangeLog

    r117978 r117981  
     12012-05-22  Dana Jansens  <danakj@chromium.org>
     2
     3        [chromium] Expand damage from the background-blurred layer to ensure readback is only including pixels below that layer
     4        https://bugs.webkit.org/show_bug.cgi?id=86884
     5
     6        Reviewed by Adrienne Walker.
     7
     8        * tests/CCDamageTrackerTest.cpp:
     9        (WebKitTests::TEST_F):
     10
    1112012-05-22  David Grogan  <dgrogan@chromium.org>
    212
  • trunk/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp

    r117864 r117981  
    395395    CCLayerImpl* child2 = root->children()[1].get();
    396396
     397    // Allow us to set damage on child1 too.
     398    child1->setDrawsContent(true);
     399
    397400    WebFilterOperations filters;
    398401    filters.append(WebFilterOperation::createBlurFilter(2));
     
    436439    EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
    437440
    438     // CASE 3: Setting this update rect outside the contentBounds of the blurred
     441    // CASE 3: Setting this update rect outside the blurred contentBounds of the blurred
    439442    // child1 will not cause it to be expanded.
    440443    root->setUpdateRect(FloatRect(30, 30, 2, 2));
     
    448451    EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
    449452
    450     // CASE 4: Setting the update rect on child2, which is above child1, will
     453    // CASE 4: Setting this update rect inside the blurred contentBounds but outside the
     454    // original contentBounds of the blurred child1 will cause it to be expanded.
     455    root->setUpdateRect(FloatRect(99, 99, 1, 1));
     456
     457    emulateDrawingOneFrame(root.get());
     458
     459    rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
     460    // Damage on the root should be: position of updateRect (99, 99), expanded
     461    // by the blurring on child1, but since it is 1 pixel outside the layer, the
     462    // expanding should be reduced by 1.
     463    expectedDamageRect = FloatRect(99, 99, 1, 1);
     464    expectedDamageRect.move(-outsetLeft + 1, -outsetTop + 1);
     465    expectedDamageRect.expand(outsetLeft + outsetRight - 1, outsetTop + outsetBottom - 1);
     466    EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
     467
     468    // CASE 5: Setting the update rect on child2, which is above child1, will
    451469    // not get blurred by child1, so it does not need to get expanded.
    452470    child2->setUpdateRect(FloatRect(0, 0, 1, 1));
     
    457475    // Damage on child2 should be: position of updateRect offset by the child's position (11, 11), and not expanded by anything.
    458476    expectedDamageRect = FloatRect(11, 11, 1, 1);
     477    EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
     478
     479    // CASE 6: Setting the update rect on child1 will also blur the damage, so
     480    // that any pixels needed for the blur are redrawn in the current frame.
     481    child1->setUpdateRect(FloatRect(0, 0, 1, 1));
     482
     483    emulateDrawingOneFrame(root.get());
     484
     485    rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
     486    // Damage on child1 should be: position of updateRect offset by the child's position (100, 100), and expanded by the damage.
     487    expectedDamageRect = FloatRect(100, 100, 1, 1);
     488    expectedDamageRect.move(-outsetLeft, -outsetTop);
     489    expectedDamageRect.expand(outsetLeft + outsetRight, outsetTop + outsetBottom);
    459490    EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
    460491}
Note: See TracChangeset for help on using the changeset viewer.