Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBox.cpp

Issue 2229643002: Don't invalidate paint on background image change if it's obscured (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@BackgroundObscured
Patch Set: Rebase Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed. 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed.
7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 1463 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 } 1474 }
1475 1475
1476 void LayoutBox::paintMask(const PaintInfo& paintInfo, const LayoutPoint& paintOf fset) const 1476 void LayoutBox::paintMask(const PaintInfo& paintInfo, const LayoutPoint& paintOf fset) const
1477 { 1477 {
1478 BoxPainter(*this).paintMask(paintInfo, paintOffset); 1478 BoxPainter(*this).paintMask(paintInfo, paintOffset);
1479 } 1479 }
1480 1480
1481 void LayoutBox::imageChanged(WrappedImagePtr image, const IntRect*) 1481 void LayoutBox::imageChanged(WrappedImagePtr image, const IntRect*)
1482 { 1482 {
1483 // TODO(chrishtr): support PaintInvalidationDelayedFull for animated border images. 1483 // TODO(chrishtr): support PaintInvalidationDelayedFull for animated border images.
1484 if ((style()->borderImage().image() && style()->borderImage().image()->data( ) == image) 1484 if ((styleRef().borderImage().image() && styleRef().borderImage().image()->d ata() == image)
1485 || (style()->maskBoxImage().image() && style()->maskBoxImage().image()-> data() == image)) { 1485 || (styleRef().maskBoxImage().image() && styleRef().maskBoxImage().image ()->data() == image)) {
1486 setShouldDoFullPaintInvalidation(); 1486 setShouldDoFullPaintInvalidation();
1487 return; 1487 } else {
1488 for (const FillLayer* layer = &styleRef().maskLayers(); layer; layer = l ayer->next()) {
1489 if (layer->image() && image == layer->image()->data()) {
1490 setShouldDoFullPaintInvalidation();
1491 break;
1492 }
1493 }
1494 }
1495
1496 if (!isDocumentElement() && !backgroundStolenForBeingBody()) {
1497 for (const FillLayer* layer = &styleRef().backgroundLayers(); layer; lay er = layer->next()) {
1498 if (layer->image() && image == layer->image()->data()) {
1499 invalidateBackgroundObscurationStatus();
1500 bool maybeAnimated = layer->image()->cachedImage() && layer->ima ge()->cachedImage()->getImage() && layer->image()->cachedImage()->getImage()->ma ybeAnimated();
1501 if (maybeAnimated)
1502 setMayNeedPaintInvalidationAnimatgedBackgroundImage();
1503 else
1504 setShouldDoFullPaintInvalidation();
1505 break;
1506 }
1507 }
1488 } 1508 }
1489 1509
1490 ShapeValue* shapeOutsideValue = style()->shapeOutside(); 1510 ShapeValue* shapeOutsideValue = style()->shapeOutside();
1491 if (!frameView()->isInPerformLayout() && isFloating() && shapeOutsideValue & & shapeOutsideValue->image() && shapeOutsideValue->image()->data() == image) { 1511 if (!frameView()->isInPerformLayout() && isFloating() && shapeOutsideValue & & shapeOutsideValue->image() && shapeOutsideValue->image()->data() == image) {
1492 ShapeOutsideInfo& info = ShapeOutsideInfo::ensureInfo(*this); 1512 ShapeOutsideInfo& info = ShapeOutsideInfo::ensureInfo(*this);
1493 if (!info.isComputingShape()) { 1513 if (!info.isComputingShape()) {
1494 info.markShapeAsDirty(); 1514 info.markShapeAsDirty();
1495 markShapeOutsideDependentsForLayout(); 1515 markShapeOutsideDependentsForLayout();
1496 } 1516 }
1497 } 1517 }
1498
1499 if (!invalidatePaintOfLayerRectsForImage(image, style()->backgroundLayers(), true))
1500 invalidatePaintOfLayerRectsForImage(image, style()->maskLayers(), false) ;
1501 } 1518 }
1502 1519
1503 ResourcePriority LayoutBox::computeResourcePriority() const 1520 ResourcePriority LayoutBox::computeResourcePriority() const
1504 { 1521 {
1505 LayoutRect viewBounds = viewRect(); 1522 LayoutRect viewBounds = viewRect();
1506 LayoutRect objectBounds = LayoutRect(absoluteContentBox()); 1523 LayoutRect objectBounds = LayoutRect(absoluteContentBox());
1507 1524
1508 // The object bounds might be empty right now, so intersects will fail since it doesn't deal 1525 // The object bounds might be empty right now, so intersects will fail since it doesn't deal
1509 // with empty rects. Use LayoutRect::contains in that case. 1526 // with empty rects. Use LayoutRect::contains in that case.
1510 bool isVisible; 1527 bool isVisible;
1511 if (!objectBounds.isEmpty()) 1528 if (!objectBounds.isEmpty())
1512 isVisible = viewBounds.intersects(objectBounds); 1529 isVisible = viewBounds.intersects(objectBounds);
1513 else 1530 else
1514 isVisible = viewBounds.contains(objectBounds); 1531 isVisible = viewBounds.contains(objectBounds);
1515 1532
1516 LayoutRect screenRect; 1533 LayoutRect screenRect;
1517 if (!objectBounds.isEmpty()) { 1534 if (!objectBounds.isEmpty()) {
1518 screenRect = viewBounds; 1535 screenRect = viewBounds;
1519 screenRect.intersect(objectBounds); 1536 screenRect.intersect(objectBounds);
1520 } 1537 }
1521 1538
1522 int screenArea = 0; 1539 int screenArea = 0;
1523 if (!screenRect.isEmpty() && isVisible) 1540 if (!screenRect.isEmpty() && isVisible)
1524 screenArea = static_cast<uint32_t>(screenRect.width() * screenRect.heigh t()); 1541 screenArea = static_cast<uint32_t>(screenRect.width() * screenRect.heigh t());
1525 return ResourcePriority(isVisible ? ResourcePriority::Visible : ResourcePrio rity::NotVisible, screenArea); 1542 return ResourcePriority(isVisible ? ResourcePriority::Visible : ResourcePrio rity::NotVisible, screenArea);
1526 } 1543 }
1527 1544
1528 bool LayoutBox::invalidatePaintOfLayerRectsForImage(WrappedImagePtr image, const FillLayer& layers, bool drawingBackground) 1545 bool LayoutBox::intersectsVisibleViewport() const
1529 {
1530 if (drawingBackground && (isDocumentElement() || backgroundStolenForBeingBod y()))
1531 return false;
1532 for (const FillLayer* curLayer = &layers; curLayer; curLayer = curLayer->nex t()) {
1533 if (curLayer->image() && image == curLayer->image()->data()) {
1534 bool maybeAnimated = curLayer->image()->cachedImage() && curLayer->i mage()->cachedImage()->getImage() && curLayer->image()->cachedImage()->getImage( )->maybeAnimated();
1535 if (maybeAnimated && drawingBackground)
1536 setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull);
1537 else
1538 setShouldDoFullPaintInvalidation();
1539
1540 if (drawingBackground)
1541 invalidateBackgroundObscurationStatus();
1542 return true;
1543 }
1544 }
1545 return false;
1546 }
1547
1548 bool LayoutBox::intersectsVisibleViewport()
1549 { 1546 {
1550 LayoutRect rect = visualOverflowRect(); 1547 LayoutRect rect = visualOverflowRect();
1551 LayoutView* layoutView = view(); 1548 LayoutView* layoutView = view();
1552 while (layoutView->frame()->ownerLayoutObject()) 1549 while (layoutView->frame()->ownerLayoutObject())
1553 layoutView = layoutView->frame()->ownerLayoutObject()->view(); 1550 layoutView = layoutView->frame()->ownerLayoutObject()->view();
1554 mapToVisualRectInAncestorSpace(layoutView, rect); 1551 mapToVisualRectInAncestorSpace(layoutView, rect);
1555 return rect.intersects(LayoutRect(layoutView->frameView()->getScrollableArea ()->visibleContentRectDouble())); 1552 return rect.intersects(LayoutRect(layoutView->frameView()->getScrollableArea ()->visibleContentRectDouble()));
1556 } 1553 }
1557 1554
1558 PaintInvalidationReason LayoutBox::invalidatePaintIfNeeded(const PaintInvalidati onState& paintInvalidationState) 1555 PaintInvalidationReason LayoutBox::invalidatePaintIfNeeded(const PaintInvalidati onState& paintInvalidationState)
1559 { 1556 {
1560 if (hasBoxDecorationBackground() 1557 if (hasBoxDecorationBackground()
1561 // We also paint overflow controls in background phase. 1558 // We also paint overflow controls in background phase.
1562 || (hasOverflowClip() && getScrollableArea()->hasOverflowControls())) { 1559 || (hasOverflowClip() && getScrollableArea()->hasOverflowControls())) {
1563 PaintLayer& layer = paintInvalidationState.paintingLayer(); 1560 PaintLayer& layer = paintInvalidationState.paintingLayer();
1564 if (layer.layoutObject() != this) 1561 if (layer.layoutObject() != this)
1565 layer.setNeedsPaintPhaseDescendantBlockBackgrounds(); 1562 layer.setNeedsPaintPhaseDescendantBlockBackgrounds();
1566 } 1563 }
1567 1564
1568 PaintInvalidationReason fullInvalidationReason = fullPaintInvalidationReason ();
1569 // If the current paint invalidation reason is PaintInvalidationDelayedFull, then this paint invalidation can delayed if the
1570 // LayoutBox in question is not on-screen. The logic to decide whether this is appropriate exists at the site of the original
1571 // paint invalidation that chose PaintInvalidationDelayedFull.
1572 if (fullInvalidationReason == PaintInvalidationDelayedFull) {
1573 if (!intersectsVisibleViewport())
1574 return PaintInvalidationDelayedFull;
1575
1576 // Reset state back to regular full paint invalidation if the object is onscreen.
1577 setShouldDoFullPaintInvalidation(PaintInvalidationFull);
1578 }
1579
1580 PaintInvalidationReason reason = LayoutBoxModelObject::invalidatePaintIfNeed ed(paintInvalidationState); 1565 PaintInvalidationReason reason = LayoutBoxModelObject::invalidatePaintIfNeed ed(paintInvalidationState);
1581 1566
1582 if (PaintLayerScrollableArea* area = getScrollableArea()) 1567 if (PaintLayerScrollableArea* area = getScrollableArea())
1583 area->invalidatePaintOfScrollControlsIfNeeded(paintInvalidationState); 1568 area->invalidatePaintOfScrollControlsIfNeeded(paintInvalidationState);
1584 1569
1585 // This is for the next invalidatePaintIfNeeded so must be at the end. 1570 // This is for the next invalidatePaintIfNeeded so must be at the end.
1586 savePreviousBoxSizesIfNeeded(); 1571 savePreviousBoxSizesIfNeeded();
1587 return reason; 1572 return reason;
1588 } 1573 }
1589 1574
(...skipping 2388 matching lines...) Expand 10 before | Expand all | Expand 10 after
3978 if (scrollableArea->hasVerticalScrollbar() && !scrollableArea->layerForV erticalScrollbar()) 3963 if (scrollableArea->hasVerticalScrollbar() && !scrollableArea->layerForV erticalScrollbar())
3979 return true; 3964 return true;
3980 } 3965 }
3981 return false; 3966 return false;
3982 } 3967 }
3983 3968
3984 PaintInvalidationReason LayoutBox::getPaintInvalidationReason(const PaintInvalid ationState& paintInvalidationState, 3969 PaintInvalidationReason LayoutBox::getPaintInvalidationReason(const PaintInvalid ationState& paintInvalidationState,
3985 const LayoutRect& oldBounds, const LayoutPoint& oldLocation, const LayoutRec t& newBounds, const LayoutPoint& newLocation) const 3970 const LayoutRect& oldBounds, const LayoutPoint& oldLocation, const LayoutRec t& newBounds, const LayoutPoint& newLocation) const
3986 { 3971 {
3987 PaintInvalidationReason invalidationReason = LayoutBoxModelObject::getPaintI nvalidationReason(paintInvalidationState, oldBounds, oldLocation, newBounds, new Location); 3972 PaintInvalidationReason invalidationReason = LayoutBoxModelObject::getPaintI nvalidationReason(paintInvalidationState, oldBounds, oldLocation, newBounds, new Location);
3988 if (isFullPaintInvalidationReason(invalidationReason)) 3973
3974 if (isFullPaintInvalidationReason(invalidationReason) && invalidationReason != PaintInvalidationDelayedFull)
3989 return invalidationReason; 3975 return invalidationReason;
3990 3976
3977 if (mayNeedPaintInvalidationAnimatedBackgroundImage() && !backgroundIsKnownT oBeObscured())
3978 invalidationReason = PaintInvalidationDelayedFull;
3979
3980 // If the current paint invalidation reason is PaintInvalidationDelayedFull, then this paint invalidation can delayed if the
3981 // LayoutBox in question is not on-screen. The logic to decide whether this is appropriate exists at the site of the original
3982 // paint invalidation that chose PaintInvalidationDelayedFull.
3983 if (invalidationReason == PaintInvalidationDelayedFull) {
3984 // Do regular full paint invalidation if the object is onscreen.
3985 return intersectsVisibleViewport() ? PaintInvalidationFull : PaintInvali dationDelayedFull;
3986 }
3987
3991 if (isLayoutView()) { 3988 if (isLayoutView()) {
3992 const LayoutView* layoutView = toLayoutView(this); 3989 const LayoutView* layoutView = toLayoutView(this);
3993 // In normal compositing mode, root background doesn't need to be invali dated for 3990 // In normal compositing mode, root background doesn't need to be invali dated for
3994 // box changes, because the background always covers the whole document rect 3991 // box changes, because the background always covers the whole document rect
3995 // and clipping is done by compositor()->m_containerLayer. Also the scro llbars 3992 // and clipping is done by compositor()->m_containerLayer. Also the scro llbars
3996 // are always composited. There are no other box decoration on the Layou tView thus 3993 // are always composited. There are no other box decoration on the Layou tView thus
3997 // we can safely exit here. 3994 // we can safely exit here.
3998 if (layoutView->usesCompositing() && (!document().settings() || !documen t().settings()->rootLayerScrolls())) 3995 if (layoutView->usesCompositing() && (!document().settings() || !documen t().settings()->rootLayerScrolls()))
3999 return invalidationReason; 3996 return invalidationReason;
4000 } 3997 }
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after
4994 m_rareData->m_snapAreas->remove(&snapArea); 4991 m_rareData->m_snapAreas->remove(&snapArea);
4995 } 4992 }
4996 } 4993 }
4997 4994
4998 SnapAreaSet* LayoutBox::snapAreas() const 4995 SnapAreaSet* LayoutBox::snapAreas() const
4999 { 4996 {
5000 return m_rareData ? m_rareData->m_snapAreas.get() : nullptr; 4997 return m_rareData ? m_rareData->m_snapAreas.get() : nullptr;
5001 } 4998 }
5002 4999
5003 } // namespace blink 5000 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBox.h ('k') | third_party/WebKit/Source/core/layout/LayoutImage.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698