Title: [135629] trunk
Revision
135629
Author
[email protected]
Date
2012-11-23 10:43:51 -0800 (Fri, 23 Nov 2012)

Log Message

Adding occlusion detection to reduce overdraw in RenderBox background rendering
https://bugs.webkit.org/show_bug.cgi?id=102557

Reviewed by Stephen White.

Source/WebCore:

Adding hasAlpha method to all classes dervived from CSSImageValue and
StyleImage, in order to support occlusion testing.
This allows the FillLayer recursion to stop early when an opaque layer
is encountered while applying a CSS background style. This also allows
the elimination of background color application when the background is
completely covered by an image.  The optimization also skips the
clearing of the page's root element when the page background is
entirely covered by an image (e.g a tiled bitmap or a gradient)

Test: fast/backgrounds/background-opaque-images-over-color.html

* css/CSSCrossfadeValue.cpp:
(WebCore::subimageHasAlpha):
(WebCore):
(WebCore::CSSCrossfadeValue::isPending):
(WebCore::CSSCrossfadeValue::hasAlpha):
* css/CSSCrossfadeValue.h:
(CSSCrossfadeValue):
* css/CSSGradientValue.cpp:
(WebCore::CSSGradientValue::hasAlpha):
(WebCore):
* css/CSSGradientValue.h:
(CSSGradientValue):
* css/CSSImageGeneratorValue.cpp:
(WebCore::CSSImageGeneratorValue::hasAlpha):
(WebCore):
* css/CSSImageGeneratorValue.h:
(CSSImageGeneratorValue):
* css/CSSImageValue.cpp:
(WebCore::CSSImageValue::hasAlpha):
(WebCore):
* css/CSSImageValue.h:
(WebCore):
(CSSImageValue):
* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::currentFrameHasAlpha):
Test whether a cached image has alpha, with side effect of ensuring
the image is in cache. (new method)
(WebCore):
* loader/cache/CachedImage.h:
(CachedImage):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::paintFillLayers):
Added layer recursion early exit when an opaque layer is encountered.
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
Eliminated background color fill when the layer contains an opaque
image that covers the entire RenderBox.
* rendering/style/FillLayer.cpp:
(WebCore::FillLayer::hasOpaqueImage):
Returns true if the layer's image is known to be fully opaque.
(WebCore):
(WebCore::FillLayer::hasRepeatXY):
* rendering/style/FillLayer.h:
(FillLayer):
* rendering/style/StyleCachedImage.cpp:
(WebCore::StyleCachedImage::hasAlpha):
(WebCore):
* rendering/style/StyleCachedImage.h:
(StyleCachedImage):
* rendering/style/StyleCachedImageSet.cpp:
(WebCore::StyleCachedImageSet::hasAlpha):
(WebCore):
* rendering/style/StyleCachedImageSet.h:
(StyleCachedImageSet):
* rendering/style/StyleGeneratedImage.cpp:
(WebCore::StyleGeneratedImage::hasAlpha):
(WebCore):
* rendering/style/StyleGeneratedImage.h:
(StyleGeneratedImage):
* rendering/style/StyleImage.h:
(StyleImage):
* rendering/style/StylePendingImage.h:
(WebCore::StylePendingImage::hasAlpha):

LayoutTests:

New test exercises different CSS background style use cases that
are candidates for optimization by occlusion culling.

* fast/backgrounds/background-opaque-images-over-color-expected.txt: Added.
* fast/backgrounds/background-opaque-images-over-color.html: Added.
* platform/chromium/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (135628 => 135629)


--- trunk/LayoutTests/ChangeLog	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/LayoutTests/ChangeLog	2012-11-23 18:43:51 UTC (rev 135629)
@@ -1,3 +1,17 @@
+2012-11-23  Justin Novosad  <[email protected]>
+
+        Adding occlusion detection to reduce overdraw in RenderBox background rendering
+        https://bugs.webkit.org/show_bug.cgi?id=102557
+
+        Reviewed by Stephen White.
+
+        New test exercises different CSS background style use cases that
+        are candidates for optimization by occlusion culling.
+
+        * fast/backgrounds/background-opaque-images-over-color-expected.txt: Added.
+        * fast/backgrounds/background-opaque-images-over-color.html: Added.
+        * platform/chromium/TestExpectations:
+
 2012-11-23  Robert Kroeger  <[email protected]>
 
         Gardening: updated expectations (pass/timeout) for

Added: trunk/LayoutTests/fast/backgrounds/background-opaque-images-over-color-expected.txt (0 => 135629)


--- trunk/LayoutTests/fast/backgrounds/background-opaque-images-over-color-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/backgrounds/background-opaque-images-over-color-expected.txt	2012-11-23 18:43:51 UTC (rev 135629)
@@ -0,0 +1,32 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x108
+  RenderBlock {HTML} at (0,0) size 800x108
+    RenderBody {BODY} at (8,8) size 784x0
+      RenderBlock {DIV} at (0,0) size 784x0
+        RenderBlock (floating) {DIV} at (0,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (20,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (40,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (60,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (80,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (100,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (120,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (140,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (160,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (180,0) size 20x100 [bgcolor=#FF0000]
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x108
+  RenderBlock {HTML} at (0,0) size 800x108
+    RenderBody {BODY} at (8,8) size 784x0
+      RenderBlock {DIV} at (0,0) size 784x0
+        RenderBlock (floating) {DIV} at (0,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (20,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (40,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (60,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (80,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (100,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (120,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (140,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (160,0) size 20x100 [bgcolor=#FF0000]
+        RenderBlock (floating) {DIV} at (180,0) size 20x100 [bgcolor=#FF0000]

Added: trunk/LayoutTests/fast/backgrounds/background-opaque-images-over-color.html (0 => 135629)


--- trunk/LayoutTests/fast/backgrounds/background-opaque-images-over-color.html	                        (rev 0)
+++ trunk/LayoutTests/fast/backgrounds/background-opaque-images-over-color.html	2012-11-23 18:43:51 UTC (rev 135629)
@@ -0,0 +1,66 @@
+<!doctype html>
+<html>
+<head>
+<!-- Test passes when a green rectangle is displayed.
+These are all drawing cases that can be optimized by occlusion culling
+The fix for bug 102557 optimizes cases 1, 2, 3, 6, 7, and 8-->
+<style type="text/css" media="screen">
+    .redBack {
+        width:20px;
+        height:100px;
+        display:block;
+        background-repeat: repeat;
+        background-color: red;
+        background-position:0px 0px, 0px 0px;
+        float: left;
+    }
+</style>
+</head>
+<body>
+<div>
+    <div id="case_1" class="redBack" style="background-image: url(../../http/tests/multipart/resources/green-100x100.png)"></div>
+    <div id="case_2" class="redBack" style="background-image: -webkit-linear-gradient(top, green, green)"></div>
+    <div id="case_3" class="redBack" style="background-image: -webkit-cross-fade(url(../../http/tests/multipart/resources/green-100x100.png), url(../../http/tests/multipart/resources/green-100x100.png), 50%)"></div>
+    <div id="case_4" class="redBack" style="background-repeat: no-repeat; background-image: url(../../http/tests/multipart/resources/green-100x100.png)"></div>
+    <div id="case_5" class="redBack" style="background-repeat: repeat-x; background-image: url(../../http/tests/multipart/resources/green-100x100.png)"></div>
+    <div id="case_6" class="redBack" style="background-image: url(../../http/tests/multipart/resources/green-100x100.png),url(resources/64x32-red.png)"></div>
+    <div id="case_7" class="redBack" style="background-image: -webkit-linear-gradient(top, green, green),url(resources/64x32-red.png)"></div>
+    <div id="case_8" class="redBack" style="background-image: -webkit-cross-fade(url(../../http/tests/multipart/resources/green-100x100.png),url(../../http/tests/multipart/resources/green-100x100.png), 50%),url(resources/64x32-red.png)"></div>
+    <div id="case_9" class="redBack" style="background-repeat: no-repeat; background-image: url(../../http/tests/multipart/resources/green-100x100.png),url(resources/64x32-red.png)"></div>
+    <div id="case_10" class="redBack" style="background-repeat: repeat-x; background-image: url(../../http/tests/multipart/resources/green-100x100.png),url(resources/64x32-red.png)"></div>
+</div>
+</body>
+</html>
+<!doctype html>
+<html>
+<head>
+<!-- Test passes when a green rectangle is displayed.
+These are all drawing cases that can be optimized by occlusion culling
+The fix for bug 102557 optimizes cases 1, 2, 3, 6, 7, and 8-->
+<style type="text/css" media="screen">
+    .redBack {
+        width:20px;
+        height:100px;
+        display:block;
+        background-repeat: repeat;
+        background-color: red;
+        background-position:0px 0px, 0px 0px;
+        float: left;
+    }
+</style>
+</head>
+<body>
+<div>
+    <div id="case_1" class="redBack" style="background-image: url(../../http/tests/multipart/resources/green-100x100.png)"></div>
+    <div id="case_2" class="redBack" style="background-image: -webkit-linear-gradient(top, green, green)"></div>
+    <div id="case_3" class="redBack" style="background-image: -webkit-cross-fade(url(../../http/tests/multipart/resources/green-100x100.png), url(../../http/tests/multipart/resources/green-100x100.png), 50%)"></div>
+    <div id="case_4" class="redBack" style="background-repeat: no-repeat; background-image: url(../../http/tests/multipart/resources/green-100x100.png)"></div>
+    <div id="case_5" class="redBack" style="background-repeat: repeat-x; background-image: url(../../http/tests/multipart/resources/green-100x100.png)"></div>
+    <div id="case_6" class="redBack" style="background-image: url(../../http/tests/multipart/resources/green-100x100.png),url(resources/64x32-red.png)"></div>
+    <div id="case_7" class="redBack" style="background-image: -webkit-linear-gradient(top, green, green),url(resources/64x32-red.png)"></div>
+    <div id="case_8" class="redBack" style="background-image: -webkit-cross-fade(url(../../http/tests/multipart/resources/green-100x100.png),url(../../http/tests/multipart/resources/green-100x100.png), 50%),url(resources/64x32-red.png)"></div>
+    <div id="case_9" class="redBack" style="background-repeat: no-repeat; background-image: url(../../http/tests/multipart/resources/green-100x100.png),url(resources/64x32-red.png)"></div>
+    <div id="case_10" class="redBack" style="background-repeat: repeat-x; background-image: url(../../http/tests/multipart/resources/green-100x100.png),url(resources/64x32-red.png)"></div>
+</div>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/chromium/TestExpectations (135628 => 135629)


--- trunk/LayoutTests/platform/chromium/TestExpectations	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/LayoutTests/platform/chromium/TestExpectations	2012-11-23 18:43:51 UTC (rev 135629)
@@ -1263,6 +1263,9 @@
 
 webkit.org/b/60118 [ Mac ] svg/dom/SVGScriptElement/script-set-href.svg [ Failure Pass ]
 
+# New test in need of new baselines
+webkit.org/b/102557 fast/backgrounds/background-opaque-images-over-color.html [ Pass ImageOnlyFailure Failure Missing ]
+
 # Introduced due to BUGWK53512, fails under Skia right now
 webkit.org/b/65939 svg/custom/getBBox-path.svg [ Failure ]
 

Modified: trunk/LayoutTests/platform/mac/TestExpectations (135628 => 135629)


--- trunk/LayoutTests/platform/mac/TestExpectations	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2012-11-23 18:43:51 UTC (rev 135629)
@@ -468,6 +468,9 @@
 media/track/track-cue-rendering-vertical.html
 media/track/track-webvtt-tc028-unsupported-markup.html
 
+# Test needs new baselines https://bugs.webkit.org/show_bug.cgi?id=102557
+fast/backgrounds/background-opaque-images-over-color.html
+
 # Tests for MediaSource API. Feature is not yet functional.
 # https://bugs.webkit.org/show_bug.cgi?id=64731
 http/tests/media/media-source/

Modified: trunk/Source/WebCore/ChangeLog (135628 => 135629)


--- trunk/Source/WebCore/ChangeLog	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/ChangeLog	2012-11-23 18:43:51 UTC (rev 135629)
@@ -1,5 +1,87 @@
 2012-11-23  Justin Novosad  <[email protected]>
 
+        Adding occlusion detection to reduce overdraw in RenderBox background rendering
+        https://bugs.webkit.org/show_bug.cgi?id=102557
+
+        Reviewed by Stephen White.
+
+        Adding hasAlpha method to all classes dervived from CSSImageValue and
+        StyleImage, in order to support occlusion testing. 
+        This allows the FillLayer recursion to stop early when an opaque layer
+        is encountered while applying a CSS background style. This also allows
+        the elimination of background color application when the background is
+        completely covered by an image.  The optimization also skips the
+        clearing of the page's root element when the page background is
+        entirely covered by an image (e.g a tiled bitmap or a gradient)
+
+        Test: fast/backgrounds/background-opaque-images-over-color.html
+
+        * css/CSSCrossfadeValue.cpp:
+        (WebCore::subimageHasAlpha):
+        (WebCore):
+        (WebCore::CSSCrossfadeValue::isPending):
+        (WebCore::CSSCrossfadeValue::hasAlpha):
+        * css/CSSCrossfadeValue.h:
+        (CSSCrossfadeValue):
+        * css/CSSGradientValue.cpp:
+        (WebCore::CSSGradientValue::hasAlpha):
+        (WebCore):
+        * css/CSSGradientValue.h:
+        (CSSGradientValue):
+        * css/CSSImageGeneratorValue.cpp:
+        (WebCore::CSSImageGeneratorValue::hasAlpha):
+        (WebCore):
+        * css/CSSImageGeneratorValue.h:
+        (CSSImageGeneratorValue):
+        * css/CSSImageValue.cpp:
+        (WebCore::CSSImageValue::hasAlpha):
+        (WebCore):
+        * css/CSSImageValue.h:
+        (WebCore):
+        (CSSImageValue):
+        * loader/cache/CachedImage.cpp:
+        (WebCore::CachedImage::currentFrameHasAlpha):
+        Test whether a cached image has alpha, with side effect of ensuring
+        the image is in cache. (new method)
+        (WebCore):
+        * loader/cache/CachedImage.h:
+        (CachedImage):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::paintFillLayers):
+        Added layer recursion early exit when an opaque layer is encountered.
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+        Eliminated background color fill when the layer contains an opaque
+        image that covers the entire RenderBox.
+        * rendering/style/FillLayer.cpp:
+        (WebCore::FillLayer::hasOpaqueImage):
+        Returns true if the layer's image is known to be fully opaque.
+        (WebCore):
+        (WebCore::FillLayer::hasRepeatXY):
+        * rendering/style/FillLayer.h:
+        (FillLayer):
+        * rendering/style/StyleCachedImage.cpp:
+        (WebCore::StyleCachedImage::hasAlpha):
+        (WebCore):
+        * rendering/style/StyleCachedImage.h:
+        (StyleCachedImage):
+        * rendering/style/StyleCachedImageSet.cpp:
+        (WebCore::StyleCachedImageSet::hasAlpha):
+        (WebCore):
+        * rendering/style/StyleCachedImageSet.h:
+        (StyleCachedImageSet):
+        * rendering/style/StyleGeneratedImage.cpp:
+        (WebCore::StyleGeneratedImage::hasAlpha):
+        (WebCore):
+        * rendering/style/StyleGeneratedImage.h:
+        (StyleGeneratedImage):
+        * rendering/style/StyleImage.h:
+        (StyleImage):
+        * rendering/style/StylePendingImage.h:
+        (WebCore::StylePendingImage::hasAlpha):
+
+2012-11-23  Justin Novosad  <[email protected]>
+
         Page background color bleeds through inner edge of div border with rounded edges
         https://bugs.webkit.org/show_bug.cgi?id=103089
 

Modified: trunk/Source/WebCore/css/CSSCrossfadeValue.cpp (135628 => 135629)


--- trunk/Source/WebCore/css/CSSCrossfadeValue.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/css/CSSCrossfadeValue.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -52,6 +52,19 @@
     return false;
 }
 
+static bool subimageHasAlpha(CSSValue* value, const RenderObject* renderer)
+{
+    if (value->isImageValue())
+        return static_cast<CSSImageValue*>(value)->hasAlpha(renderer);
+
+    if (value->isImageGeneratorValue())
+        return static_cast<CSSImageGeneratorValue*>(value)->hasAlpha(renderer);
+
+    ASSERT_NOT_REACHED();
+
+    return true;
+}
+
 static CachedImage* cachedImageForCSSValue(CSSValue* value, CachedResourceLoader* cachedResourceLoader)
 {
     if (!value)
@@ -126,6 +139,11 @@
     return subimageIsPending(m_fromValue.get()) || subimageIsPending(m_toValue.get());
 }
 
+bool CSSCrossfadeValue::hasAlpha(const RenderObject* renderer) const
+{
+    return subimageHasAlpha(m_fromValue.get(), renderer) || subimageHasAlpha(m_toValue.get(), renderer);
+}
+
 void CSSCrossfadeValue::loadSubimages(CachedResourceLoader* cachedResourceLoader)
 {
     m_cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);

Modified: trunk/Source/WebCore/css/CSSCrossfadeValue.h (135628 => 135629)


--- trunk/Source/WebCore/css/CSSCrossfadeValue.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/css/CSSCrossfadeValue.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -58,6 +58,8 @@
     IntSize fixedSize(const RenderObject*);
 
     bool isPending() const;
+    bool hasAlpha(const RenderObject*) const;
+
     void loadSubimages(CachedResourceLoader*);
 
     void setPercentage(PassRefPtr<CSSPrimitiveValue> percentageValue) { m_percentageValue = percentageValue; }

Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (135628 => 135629)


--- trunk/Source/WebCore/css/CSSGradientValue.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -462,6 +462,15 @@
     return true;
 }
 
+bool CSSGradientValue::hasAlpha(const RenderObject*) const
+{
+    for (size_t i = 0; i < m_stops.size(); ++i) {
+        if (m_stops[i].m_resolvedColor.hasAlpha())
+            return true;
+    }
+    return false;
+}
+
 void CSSGradientValue::reportBaseClassMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);

Modified: trunk/Source/WebCore/css/CSSGradientValue.h (135628 => 135629)


--- trunk/Source/WebCore/css/CSSGradientValue.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/css/CSSGradientValue.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -74,6 +74,8 @@
     IntSize fixedSize(const RenderObject*) const { return IntSize(); }
 
     bool isPending() const { return false; }
+    bool hasAlpha(const RenderObject*) const;
+
     void loadSubimages(CachedResourceLoader*) { }
     PassRefPtr<CSSGradientValue> gradientWithStylesResolved(StyleResolver*);
 

Modified: trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp (135628 => 135629)


--- trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -196,6 +196,23 @@
     return false;
 }
 
+bool CSSImageGeneratorValue::hasAlpha(const RenderObject* renderer) const
+{
+    switch (classType()) {
+    case CrossfadeClass:
+        return static_cast<const CSSCrossfadeValue*>(this)->hasAlpha(renderer);
+    case CanvasClass:
+        return true;
+    case LinearGradientClass:
+        return static_cast<const CSSLinearGradientValue*>(this)->hasAlpha(renderer);
+    case RadialGradientClass:
+        return static_cast<const CSSRadialGradientValue*>(this)->hasAlpha(renderer);
+    default:
+        ASSERT_NOT_REACHED();
+    }
+    return true;
+}
+
 void CSSImageGeneratorValue::loadSubimages(CachedResourceLoader* cachedResourceLoader)
 {
     switch (classType()) {

Modified: trunk/Source/WebCore/css/CSSImageGeneratorValue.h (135628 => 135629)


--- trunk/Source/WebCore/css/CSSImageGeneratorValue.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/css/CSSImageGeneratorValue.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -63,6 +63,7 @@
     IntSize fixedSize(const RenderObject*);
 
     bool isPending() const;
+    bool hasAlpha(const RenderObject*) const;
 
     void loadSubimages(CachedResourceLoader*);
 

Modified: trunk/Source/WebCore/css/CSSImageValue.cpp (135628 => 135629)


--- trunk/Source/WebCore/css/CSSImageValue.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/css/CSSImageValue.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -140,4 +140,9 @@
     // No need to report m_image as it is counted as part of RenderArena.
 }
 
+bool CSSImageValue::hasAlpha(const RenderObject* renderer) const
+{
+    return m_image ? m_image->hasAlpha(renderer) : true;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/css/CSSImageValue.h (135628 => 135629)


--- trunk/Source/WebCore/css/CSSImageValue.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/css/CSSImageValue.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -30,6 +30,7 @@
 class Element;
 class StyleCachedImage;
 class StyleImage;
+class RenderObject;
 
 class CSSImageValue : public CSSValue {
 public:
@@ -51,6 +52,8 @@
 
     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
 
+    bool hasAlpha(const RenderObject*) const;
+
 protected:
     CSSImageValue(ClassType, const String& url);
 

Modified: trunk/Source/WebCore/loader/cache/CachedImage.cpp (135628 => 135629)


--- trunk/Source/WebCore/loader/cache/CachedImage.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/loader/cache/CachedImage.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -475,4 +475,12 @@
 #endif
 }
 
+bool CachedImage::currentFrameHasAlpha(const RenderObject* renderer)
+{
+    Image* image = imageForRenderer(renderer);
+    if (image->isBitmapImage())
+        image->nativeImageForCurrentFrame(); // force decode
+    return image->currentFrameHasAlpha();
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/loader/cache/CachedImage.h (135628 => 135629)


--- trunk/Source/WebCore/loader/cache/CachedImage.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/loader/cache/CachedImage.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -52,6 +52,7 @@
     Image* image(); // Returns the nullImage() if the image is not available yet.
     Image* imageForRenderer(const RenderObject*); // Returns the nullImage() if the image is not available yet.
     bool hasImage() const { return m_image.get(); }
+    bool currentFrameHasAlpha(const RenderObject*); // Side effect: ensures decoded image is in cache, therefore should only be called when about to draw the image.
 
     std::pair<Image*, float> brokenImage(float deviceScaleFactor) const; // Returns an image and the image's resolution scale factor.
     bool willPaintBrokenImage() const; 

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (135628 => 135629)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -1001,7 +1001,14 @@
     if (!fillLayer)
         return;
 
-    paintFillLayers(paintInfo, c, fillLayer->next(), rect, bleedAvoidance, op, backgroundObject);
+    // FIXME : It would be possible for the following occlusion culling test to be more aggressive 
+    // on layers with no repeat by testing whether the image covers the layout rect.
+    // Testing that here would imply duplicating a lot of calculations that are currently done in
+    // RenderBoxModelOBject::paintFillLayerExtended. A more efficient solution might be to move
+    // the layer recursion into paintFillLayerExtended, or to compute the layer geometry here
+    // and pass it down.
+    if (fillLayer->next() && (!fillLayer->hasOpaqueImage(this) || !fillLayer->image()->canRender(this, style()->effectiveZoom()) || !fillLayer->hasRepeatXY()))
+        paintFillLayers(paintInfo, c, fillLayer->next(), rect, bleedAvoidance, op, backgroundObject);
     paintFillLayer(paintInfo, c, fillLayer, rect, bleedAvoidance, op, backgroundObject);
 }
 

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (135628 => 135629)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -907,8 +907,10 @@
         view()->frameView()->setContentIsOpaque(isOpaqueRoot);
     }
 
-    // Paint the color first underneath all images.
-    if (!bgLayer->next()) {
+    // Paint the color first underneath all images, culled if background image occludes it.
+    // FIXME: In the bgLayer->hasFiniteBounds() case, we could improve the culling test
+    // by verifying whether the background image covers the entire layout rect.
+    if (!bgLayer->next() && !(shouldPaintBackgroundImage && bgLayer->hasOpaqueImage(this) && bgLayer->hasRepeatXY())) {
         IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect));
         bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppliedToBackground(bleedAvoidance, box);
         if (!boxShadowShouldBeAppliedToBackground)

Modified: trunk/Source/WebCore/rendering/style/FillLayer.cpp (135628 => 135629)


--- trunk/Source/WebCore/rendering/style/FillLayer.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/style/FillLayer.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -280,4 +280,23 @@
     return true;
 }
 
+bool FillLayer::hasOpaqueImage(const RenderObject* renderer) const
+{
+    if (!m_image)
+        return false;
+
+    if (m_composite == CompositeClear || m_composite == CompositeCopy)
+        return true;
+
+    if (m_composite == CompositeSourceOver)
+        return !m_image->hasAlpha(renderer);
+
+    return false;
+}
+
+bool FillLayer::hasRepeatXY() const
+{
+    return m_repeatX == RepeatFill && m_repeatY == RepeatFill;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/style/FillLayer.h (135628 => 135629)


--- trunk/Source/WebCore/rendering/style/FillLayer.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/style/FillLayer.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -144,6 +144,9 @@
         return m_next ? m_next->hasFixedImage() : false;
     }
 
+    bool hasOpaqueImage(const RenderObject*) const;
+    bool hasRepeatXY() const;
+
     EFillLayerType type() const { return static_cast<EFillLayerType>(m_type); }
 
     void fillUnsetProperties();

Modified: trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp (135628 => 135629)


--- trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -106,4 +106,9 @@
     return m_image->imageForRenderer(renderer);
 }
 
+bool StyleCachedImage::hasAlpha(const RenderObject* renderer) const
+{
+    return m_image->currentFrameHasAlpha(renderer);
 }
+
+}

Modified: trunk/Source/WebCore/rendering/style/StyleCachedImage.h (135628 => 135629)


--- trunk/Source/WebCore/rendering/style/StyleCachedImage.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/style/StyleCachedImage.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -56,6 +56,7 @@
     virtual void addClient(RenderObject*);
     virtual void removeClient(RenderObject*);
     virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
+    virtual bool hasAlpha(const RenderObject*) const OVERRIDE;
     
 private:
     explicit StyleCachedImage(CachedImage*);

Modified: trunk/Source/WebCore/rendering/style/StyleCachedImageSet.cpp (135628 => 135629)


--- trunk/Source/WebCore/rendering/style/StyleCachedImageSet.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/style/StyleCachedImageSet.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -116,6 +116,11 @@
     return m_bestFitImage->imageForRenderer(renderer);
 }
 
+bool StyleCachedImageSet::hasAlpha(const RenderObject* renderer) const
+{
+    return m_bestFitImage->currentFrameHasAlpha(renderer);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(CSS_IMAGE_SET)

Modified: trunk/Source/WebCore/rendering/style/StyleCachedImageSet.h (135628 => 135629)


--- trunk/Source/WebCore/rendering/style/StyleCachedImageSet.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/style/StyleCachedImageSet.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -71,6 +71,7 @@
     virtual void removeClient(RenderObject*);
     virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
     virtual float imageScaleFactor() const { return m_imageScaleFactor; }
+    virtual bool hasAlpha(const RenderObject*) const OVERRIDE;
     
 private:
     StyleCachedImageSet(CachedImage*, float imageScaleFactor, CSSImageSetValue*);

Modified: trunk/Source/WebCore/rendering/style/StyleGeneratedImage.cpp (135628 => 135629)


--- trunk/Source/WebCore/rendering/style/StyleGeneratedImage.cpp	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/style/StyleGeneratedImage.cpp	2012-11-23 18:43:51 UTC (rev 135629)
@@ -89,4 +89,9 @@
     return m_imageGeneratorValue->image(renderer, size);
 }
 
+bool StyleGeneratedImage::hasAlpha(const RenderObject* renderer) const
+{
+    return m_imageGeneratorValue->hasAlpha(renderer);
 }
+
+}

Modified: trunk/Source/WebCore/rendering/style/StyleGeneratedImage.h (135628 => 135629)


--- trunk/Source/WebCore/rendering/style/StyleGeneratedImage.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/style/StyleGeneratedImage.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -51,6 +51,7 @@
     virtual void addClient(RenderObject*);
     virtual void removeClient(RenderObject*);
     virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
+    virtual bool hasAlpha(const RenderObject*) const OVERRIDE;
     
 private:
     StyleGeneratedImage(PassRefPtr<CSSImageGeneratorValue>);

Modified: trunk/Source/WebCore/rendering/style/StyleImage.h (135628 => 135629)


--- trunk/Source/WebCore/rendering/style/StyleImage.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/style/StyleImage.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -64,6 +64,7 @@
     virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const = 0;
     virtual WrappedImagePtr data() const = 0;
     virtual float imageScaleFactor() const { return 1; }
+    virtual bool hasAlpha(const RenderObject*) const = 0;
 
     ALWAYS_INLINE bool isCachedImage() const { return m_isCachedImage; }
     ALWAYS_INLINE bool isPendingImage() const { return m_isPendingImage; }

Modified: trunk/Source/WebCore/rendering/style/StylePendingImage.h (135628 => 135629)


--- trunk/Source/WebCore/rendering/style/StylePendingImage.h	2012-11-23 18:39:51 UTC (rev 135628)
+++ trunk/Source/WebCore/rendering/style/StylePendingImage.h	2012-11-23 18:43:51 UTC (rev 135629)
@@ -66,6 +66,7 @@
         ASSERT_NOT_REACHED();
         return 0;
     }
+    virtual bool hasAlpha(const RenderObject*) const { return true; }
     
 private:
     StylePendingImage(CSSValue* value)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to