Changeset 146955 in webkit
- Timestamp:
- Mar 26, 2013, 6:00:57 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r146949 r146955 1 2013-03-26 Antti Koivisto <antti@apple.com> 2 3 Test if non-immediate descendants obscure background 4 https://bugs.webkit.org/show_bug.cgi?id=113137 5 6 Reviewed by Simon Fraser. 7 8 * fast/backgrounds/obscured-background-child-style-change-expected.html: 9 * fast/backgrounds/obscured-background-child-style-change.html: 10 * fast/repaint/obscured-background-no-repaint-expected.txt: 11 * fast/repaint/obscured-background-no-repaint.html: 12 1 13 2013-03-26 Chris Fleizach <cfleizach@apple.com> 2 14 -
trunk/LayoutTests/fast/backgrounds/obscured-background-child-style-change-expected.html
r146279 r146955 8 8 .child { 9 9 position: relative; 10 background-color: rgba(0,255,0,0. 2);10 background-color: rgba(0,255,0,0.8); 11 11 width: 100px; 12 12 height: 100px; … … 17 17 </div> 18 18 </div> 19 <div class=parent> 20 <div> 21 <div class=child> 22 </div> 23 </div> 24 </div> 25 <script> 26 document.body.offsetTop; 27 if (window.testRunner) 28 testRunner.display(); 29 var children = document.getElementsByClassName("child"); 30 children[0].style.backgroundColor = "rgba(0,255,0,0.5)"; 31 children[1].style.backgroundColor = "rgba(0,255,0,0.5)"; 32 </script> -
trunk/LayoutTests/fast/backgrounds/obscured-background-child-style-change.html
r146279 r146955 7 7 } 8 8 .child { 9 position: relative;10 9 background-color: red; 11 10 width: 100px; … … 14 13 </style> 15 14 <div class=parent> 16 <div class=child> 15 <div class=child> 16 </div> 17 17 </div> 18 <div class=parent> 19 <div> 20 <div class=child> 21 </div> 22 </div> 18 23 </div> 19 24 <script> 20 25 document.body.offsetTop; 21 document.getElementsByClassName("child")[0].style.backgroundColor = "rgba(0,255,0,0.2)"; 26 if (window.testRunner) 27 testRunner.display(); 28 var children = document.getElementsByClassName("child"); 29 children[0].style.backgroundColor = "rgba(0,255,0,0.5)"; 30 children[1].style.backgroundColor = "rgba(0,255,0,0.5)"; 22 31 </script> -
trunk/LayoutTests/fast/repaint/obscured-background-no-repaint-expected.txt
r145680 r146955 9 9 TEST COMPLETE 10 10 11 12 -
trunk/LayoutTests/fast/repaint/obscured-background-no-repaint.html
r146279 r146955 33 33 } 34 34 #test3 img { 35 background-image: url(resources/animated.gif) 36 } 37 #test4 .parent { 38 position: relative; 39 height: 100px; 40 width: 100px; 41 background-color: red; 42 background-repeat: no-repeat; 43 background-position: center; 35 44 background-image: url(resources/animated.gif) 36 45 } … … 82 91 <img src="resources/apple.jpg"> 83 92 </div> 93 <div id="test4"> 94 <div class="parent"> 95 <a> 96 <div></div> 97 <div> 98 <img src="resources/apple.jpg"> 99 </div> 100 </a> 101 </div> 102 </div> 84 103 </body> 85 104 <script src="../js/resources/js-test-post.js"></script> -
trunk/Source/WebCore/ChangeLog
r146954 r146955 1 2013-03-26 Antti Koivisto <antti@apple.com> 2 3 Test if non-immediate descendants obscure background 4 https://bugs.webkit.org/show_bug.cgi?id=113137 5 6 Reviewed by Simon Fraser. 7 8 The current obscuration test only covers immediate children. We can find more cases by looking deeper into descendants. 9 10 The patch makes the test sufficiently smart to stop a heavy fully obscured gif animation on micrsoft.com. 11 12 * loader/cache/CachedImage.cpp: 13 (WebCore::CachedImage::animationAdvanced): 14 * rendering/RenderBox.cpp: 15 (WebCore::RenderBox::styleDidChange): 16 17 Invalidate parents to max test depth. 18 19 (WebCore::RenderBox::backgroundPaintedExtent): 20 21 Background painting is pixel snapped. 22 23 (WebCore::isCandidateForOpaquenessTest): 24 (WebCore::RenderBox::foregroundIsKnownToBeOpaqueInRect): 25 26 Separate foreground testing and make it recursive. 27 Add fast bailout for common static positioned case. 28 Remove maximum child count, the fast bailouts should prevent long tests. 29 Add maximum depth so we know how deep we need to invalidate in styleDidChange. 30 31 (WebCore::RenderBox::computeBackgroundIsKnownToBeObscured): 32 (WebCore): 33 * rendering/RenderBox.h: 34 (RenderBox): 35 * rendering/RenderImage.cpp: 36 (WebCore::RenderImage::foregroundIsKnownToBeOpaqueInRect): 37 (WebCore): 38 (WebCore::RenderImage::computeBackgroundIsKnownToBeObscured): 39 40 * rendering/RenderImage.h: 41 (RenderImage): 42 1 43 2013-03-26 Benjamin Poulain <bpoulain@apple.com> 2 44 -
trunk/Source/WebCore/rendering/RenderBox.cpp
r146531 r146955 90 90 // autoscroll is started. 91 91 static const int autoscrollBeltSize = 20; 92 static const unsigned backgroundObscurationTestMaxDepth = 4; 92 93 93 94 bool RenderBox::s_hadOverflowClip = false; … … 284 285 285 286 // Our opaqueness might have changed without triggering layout. 286 if (parent() && (diff == StyleDifferenceRepaint || diff == StyleDifferenceRepaintLayer)) 287 parent()->invalidateBackgroundObscurationStatus(); 287 if (diff == StyleDifferenceRepaint || diff == StyleDifferenceRepaintLayer) { 288 RenderObject* parentToInvalidate = parent(); 289 for (unsigned i = 0; i < backgroundObscurationTestMaxDepth && parentToInvalidate; ++i) { 290 parentToInvalidate->invalidateBackgroundObscurationStatus(); 291 parentToInvalidate = parentToInvalidate->parent(); 292 } 293 } 288 294 289 295 bool isBodyRenderer = isBody(); … … 1151 1157 { 1152 1158 ASSERT(hasBackground()); 1153 LayoutRect backgroundRect = borderBoxRect();1159 LayoutRect backgroundRect = pixelSnappedIntRect(borderBoxRect()); 1154 1160 1155 1161 Color backgroundColor = style()->visitedDependentColor(CSSPropertyBackgroundColor); … … 1197 1203 } 1198 1204 1205 static bool isCandidateForOpaquenessTest(RenderBox* childBox) 1206 { 1207 RenderStyle* childStyle = childBox->style(); 1208 if (childStyle->position() != StaticPosition && childBox->containingBlock() != childBox->parent()) 1209 return false; 1210 if (childStyle->visibility() != VISIBLE || childStyle->shapeOutside()) 1211 return false; 1212 if (!childBox->width() || !childBox->height()) 1213 return false; 1214 if (RenderLayer* childLayer = childBox->layer()) { 1215 #if USE(ACCELERATED_COMPOSITING) 1216 if (childLayer->isComposited()) 1217 return false; 1218 #endif 1219 // FIXME: Deal with z-index. 1220 if (!childStyle->hasAutoZIndex()) 1221 return false; 1222 if (childLayer->hasTransform() || childLayer->isTransparent() || childLayer->hasFilter()) 1223 return false; 1224 } 1225 return true; 1226 } 1227 1228 bool RenderBox::foregroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect, unsigned maxDepthToTest) const 1229 { 1230 if (!maxDepthToTest) 1231 return false; 1232 for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { 1233 if (!child->isBox()) 1234 continue; 1235 RenderBox* childBox = toRenderBox(child); 1236 if (!isCandidateForOpaquenessTest(childBox)) 1237 continue; 1238 LayoutPoint childLocation = childBox->location(); 1239 if (childBox->isRelPositioned()) 1240 childLocation.move(childBox->relativePositionOffset()); 1241 LayoutRect childLocalRect = localRect; 1242 childLocalRect.moveBy(-childLocation); 1243 if (childLocalRect.y() < 0 || childLocalRect.x() < 0) { 1244 // If there is unobscured area above/left of a static positioned box then the rect is probably not covered. 1245 if (childBox->style()->position() == StaticPosition) 1246 return false; 1247 continue; 1248 } 1249 if (childLocalRect.maxY() > childBox->height() || childLocalRect.maxX() > childBox->width()) 1250 continue; 1251 if (childBox->backgroundIsKnownToBeOpaqueInRect(childLocalRect)) 1252 return true; 1253 if (childBox->foregroundIsKnownToBeOpaqueInRect(childLocalRect, maxDepthToTest - 1)) 1254 return true; 1255 } 1256 return false; 1257 } 1258 1199 1259 bool RenderBox::computeBackgroundIsKnownToBeObscured() 1200 1260 { … … 1208 1268 1209 1269 LayoutRect backgroundRect = backgroundPaintedExtent(); 1210 // If we don't find a covering child fast there probably isn't one. 1211 static const unsigned maximumChildrenCountToTest = 4; 1212 unsigned count = 0; 1213 for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { 1214 if (++count > maximumChildrenCountToTest) 1215 break; 1216 if (!child->isBox()) 1217 continue; 1218 RenderBox* childBox = toRenderBox(child); 1219 RenderStyle* childStyle = child->style(); 1220 if (childStyle->visibility() != VISIBLE || childStyle->shapeOutside()) 1221 continue; 1222 if (childStyle->position() != StaticPosition && childBox->containingBlock() != this) 1223 continue; 1224 LayoutPoint childLocation = childBox->location(); 1225 if (childBox->isRelPositioned()) 1226 childLocation.move(childBox->relativePositionOffset()); 1227 LayoutRect childLocalBackgroundRect = backgroundRect; 1228 childLocalBackgroundRect.moveBy(-childLocation); 1229 if (RenderLayer* childLayer = childBox->layer()) { 1230 #if USE(ACCELERATED_COMPOSITING) 1231 if (childLayer->isComposited()) 1232 continue; 1233 #endif 1234 if (childLayer->zIndex() < 0) 1235 continue; 1236 if (childLayer->hasTransform() || childLayer->isTransparent()) 1237 continue; 1238 } 1239 if (childBox->backgroundIsKnownToBeOpaqueInRect(childLocalBackgroundRect)) 1240 return true; 1241 } 1242 return false; 1270 return foregroundIsKnownToBeOpaqueInRect(backgroundRect, backgroundObscurationTestMaxDepth); 1243 1271 } 1244 1272 -
trunk/Source/WebCore/rendering/RenderBox.h
r146531 r146955 595 595 596 596 LayoutRect backgroundPaintedExtent() const; 597 virtual bool foregroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect, unsigned maxDepthToTest) const; 597 598 virtual bool computeBackgroundIsKnownToBeObscured() OVERRIDE; 599 598 600 void paintBackground(const PaintInfo&, const LayoutRect&, BackgroundBleedAvoidance = BackgroundBleedNone); 599 601 -
trunk/Source/WebCore/rendering/RenderImage.cpp
r146279 r146955 485 485 } 486 486 487 bool RenderImage::computeBackgroundIsKnownToBeObscured() 488 { 487 bool RenderImage::foregroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect, unsigned maxDepthToTest) const 488 { 489 UNUSED_PARAM(maxDepthToTest); 489 490 if (!m_imageResource->hasImage() || m_imageResource->errorOccurred()) 490 491 return false; 491 492 if (m_imageResource->cachedImage() && !m_imageResource->cachedImage()->isLoaded()) 492 493 return false; 493 494 if (!contentBoxRect().contains(localRect)) 495 return false; 494 496 EFillBox backgroundClip = style()->backgroundClip(); 495 497 // Background paints under borders. … … 499 501 if ((backgroundClip == BorderFillBox || backgroundClip == PaddingFillBox) && style()->hasPadding()) 500 502 return false; 501 502 503 // Check for image with alpha. 503 504 return m_imageResource->cachedImage() && m_imageResource->cachedImage()->currentFrameKnownToBeOpaque(this); 505 } 506 507 bool RenderImage::computeBackgroundIsKnownToBeObscured() 508 { 509 if (!hasBackground()) 510 return false; 511 return foregroundIsKnownToBeOpaqueInRect(backgroundPaintedExtent(), 0); 504 512 } 505 513 -
trunk/Source/WebCore/rendering/RenderImage.h
r146835 r146955 89 89 virtual void paintReplaced(PaintInfo&, const LayoutPoint&); 90 90 91 virtual bool foregroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect, unsigned maxDepthToTest) const OVERRIDE; 91 92 virtual bool computeBackgroundIsKnownToBeObscured() OVERRIDE; 92 93
Note:
See TracChangeset
for help on using the changeset viewer.