| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/paint/PaintInvalidationCapableScrollableArea.h" | 6 #include "core/paint/PaintInvalidationCapableScrollableArea.h" |
| 7 | 7 |
| 8 #include "core/frame/Settings.h" | 8 #include "core/frame/Settings.h" |
| 9 #include "core/html/HTMLFrameOwnerElement.h" | 9 #include "core/html/HTMLFrameOwnerElement.h" |
| 10 #include "core/layout/LayoutBox.h" | 10 #include "core/layout/LayoutBox.h" |
| 11 #include "core/layout/LayoutScrollbar.h" | 11 #include "core/layout/LayoutScrollbar.h" |
| 12 #include "core/layout/LayoutScrollbarPart.h" | 12 #include "core/layout/LayoutScrollbarPart.h" |
| 13 #include "core/layout/PaintInvalidationState.h" | 13 #include "core/layout/PaintInvalidationState.h" |
| 14 #include "core/paint/PaintLayer.h" | 14 #include "core/paint/PaintLayer.h" |
| 15 #include "platform/graphics/GraphicsLayer.h" | |
| 16 | 15 |
| 17 namespace blink { | 16 namespace blink { |
| 18 | 17 |
| 19 void PaintInvalidationCapableScrollableArea::willRemoveScrollbar(Scrollbar* scro
llbar, ScrollbarOrientation orientation) | 18 void PaintInvalidationCapableScrollableArea::willRemoveScrollbar(Scrollbar* scro
llbar, ScrollbarOrientation orientation) |
| 20 { | 19 { |
| 21 if (!scrollbar->isCustomScrollbar() | 20 if (!scrollbar->isCustomScrollbar() |
| 22 && !(orientation == HorizontalScrollbar ? layerForHorizontalScrollbar()
: layerForVerticalScrollbar())) | 21 && !(orientation == HorizontalScrollbar ? layerForHorizontalScrollbar()
: layerForVerticalScrollbar())) |
| 23 boxForScrollControlPaintInvalidation().invalidateDisplayItemClient(*scro
llbar); | 22 boxForScrollControlPaintInvalidation().invalidateDisplayItemClient(*scro
llbar); |
| 24 | 23 |
| 25 ScrollableArea::willRemoveScrollbar(scrollbar, orientation); | 24 ScrollableArea::willRemoveScrollbar(scrollbar, orientation); |
| 26 } | 25 } |
| 27 | 26 |
| 28 static LayoutRect scrollControlPaintInvalidationRect(const IntRect& scrollContro
lRect, const LayoutBox& box, const PaintInvalidationState& paintInvalidationStat
e, const LayoutBoxModelObject& paintInvalidationContainer) | 27 // Returns true if the scroll control is invalidated. |
| 28 static bool invalidatePaintOfScrollControlIfNeeded(const IntRect& scrollControlR
ect, LayoutRect& previousPaintInvalidationRect, bool needsPaintInvalidation, Lay
outBox& box, const PaintInvalidationState& paintInvalidationState, const LayoutB
oxModelObject& paintInvalidationContainer) |
| 29 { | 29 { |
| 30 LayoutRect paintInvalidationRect(scrollControlRect); | 30 LayoutRect paintInvalidationRect(scrollControlRect); |
| 31 if (!paintInvalidationRect.isEmpty()) | 31 if (!paintInvalidationRect.isEmpty()) |
| 32 PaintLayer::mapRectToPaintInvalidationBacking(&box, &paintInvalidationCo
ntainer, paintInvalidationRect, &paintInvalidationState); | 32 PaintLayer::mapRectToPaintInvalidationBacking(&box, &paintInvalidationCo
ntainer, paintInvalidationRect, &paintInvalidationState); |
| 33 return paintInvalidationRect; | |
| 34 } | |
| 35 | 33 |
| 36 // Returns true if the scroll control is invalidated. | 34 if (paintInvalidationRect != previousPaintInvalidationRect) { |
| 37 static bool invalidatePaintOfScrollControlIfNeeded(const LayoutRect& newPaintInv
alidationRect, const LayoutRect& previousPaintInvalidationRect, bool needsPaintI
nvalidation, LayoutBox& box, const LayoutBoxModelObject& paintInvalidationContai
ner) | |
| 38 { | |
| 39 bool shouldInvalidateNewRect = needsPaintInvalidation; | |
| 40 if (newPaintInvalidationRect != previousPaintInvalidationRect) { | |
| 41 box.invalidatePaintUsingContainer(paintInvalidationContainer, previousPa
intInvalidationRect, PaintInvalidationScroll); | 35 box.invalidatePaintUsingContainer(paintInvalidationContainer, previousPa
intInvalidationRect, PaintInvalidationScroll); |
| 42 shouldInvalidateNewRect = true; | 36 previousPaintInvalidationRect = paintInvalidationRect; |
| 37 needsPaintInvalidation = true; |
| 43 } | 38 } |
| 44 if (shouldInvalidateNewRect) { | 39 |
| 45 box.invalidatePaintUsingContainer(paintInvalidationContainer, newPaintIn
validationRect, PaintInvalidationScroll); | 40 if (needsPaintInvalidation) { |
| 46 box.enclosingLayer()->setNeedsRepaint(); | 41 box.invalidatePaintUsingContainer(paintInvalidationContainer, paintInval
idationRect, PaintInvalidationScroll); |
| 47 return true; | 42 return true; |
| 48 } | 43 } |
| 44 |
| 49 return false; | 45 return false; |
| 50 } | 46 } |
| 51 | 47 |
| 52 struct ScrollbarPaintInvalidationData { | 48 static void invalidatePaintOfScrollbarIfNeeded(Scrollbar* scrollbar, GraphicsLay
er* scrollbarGraphicsLayer, LayoutRect& previousPaintInvalidationRect, bool need
sPaintInvalidation, LayoutBox& box, const PaintInvalidationState& paintInvalidat
ionState, const LayoutBoxModelObject& paintInvalidationContainer) |
| 53 Scrollbar* scrollbar; | |
| 54 GraphicsLayer* graphicsLayer; | |
| 55 LayoutRect& previousPaintInvalidatioRect; | |
| 56 | |
| 57 }; | |
| 58 | |
| 59 static void invalidatePaintOfScrollbarIfNeeded(Scrollbar* scrollbar, GraphicsLay
er* graphicsLayer, bool& previouslyWasOverlay, LayoutRect& previousPaintInvalida
tionRect, bool needsPaintInvalidationArg, LayoutBox& box, const PaintInvalidatio
nState& paintInvalidationState, const LayoutBoxModelObject& paintInvalidationCon
tainer) | |
| 60 { | 49 { |
| 61 bool isOverlay = scrollbar && scrollbar->isOverlayScrollbar(); | 50 IntRect scrollbarRect = scrollbar && !scrollbarGraphicsLayer ? scrollbar->fr
ameRect() : IntRect(); |
| 62 | 51 if (!invalidatePaintOfScrollControlIfNeeded(scrollbarRect, previousPaintInva
lidationRect, needsPaintInvalidation, box, paintInvalidationState, paintInvalida
tionContainer)) |
| 63 // Calculate paint invalidation rect of the scrollbar, except overlay compos
ited scrollbars because we invalidate the graphics layer only. | 52 return; |
| 64 LayoutRect newPaintInvalidationRect; | 53 if (!scrollbar) |
| 65 if (scrollbar && !(graphicsLayer && isOverlay)) | |
| 66 newPaintInvalidationRect = scrollControlPaintInvalidationRect(scrollbar-
>frameRect(), box, paintInvalidationState, paintInvalidationContainer); | |
| 67 | |
| 68 bool needsPaintInvalidation = needsPaintInvalidationArg; | |
| 69 if (graphicsLayer && needsPaintInvalidation) { | |
| 70 graphicsLayer->setNeedsDisplay(); | |
| 71 graphicsLayer->setContentsNeedsDisplay(); | |
| 72 // If the scrollbar needs paint invalidation but didn't change location/
size or the scrollbar is an | |
| 73 // overlay scrollbar (paint invalidation rect is empty), invalidating th
e graphics layer is enough. | |
| 74 // Otherwise invalidatePaintOfScrollControlIfNeeded() below will invalid
ate the old and new location | |
| 75 // of the scrollbar on the box's paint invalidation container to ensure
newly expanded/shrunk areas | |
| 76 // of the box to be invalidated. | |
| 77 needsPaintInvalidation = false; | |
| 78 } | |
| 79 | |
| 80 // Invalidate the box's display item client if the box's padding box size is
affected by change of the | |
| 81 // non-overlay scrollbar width. We detect change of paint invalidation rect
size instead of change of | |
| 82 // scrollbar width change, which may have some false-positives (e.g. the scr
ollbar changed length but | |
| 83 // not width) but won't invalidate more than expected because in the false-p
ositive case the box must | |
| 84 // have changed size and have been invalidated. | |
| 85 LayoutSize newScrollbarUsedSpaceInBox; | |
| 86 if (!isOverlay) | |
| 87 newScrollbarUsedSpaceInBox = newPaintInvalidationRect.size(); | |
| 88 LayoutSize previousScrollbarUsedSpaceInBox; | |
| 89 if (!previouslyWasOverlay) | |
| 90 previousScrollbarUsedSpaceInBox= previousPaintInvalidationRect.size(); | |
| 91 if (newScrollbarUsedSpaceInBox != previousScrollbarUsedSpaceInBox) | |
| 92 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(box, Pai
ntInvalidationScroll, nullptr); | |
| 93 | |
| 94 bool invalidated = invalidatePaintOfScrollControlIfNeeded(newPaintInvalidati
onRect, previousPaintInvalidationRect, needsPaintInvalidation, box, paintInvalid
ationContainer); | |
| 95 | |
| 96 previousPaintInvalidationRect = newPaintInvalidationRect; | |
| 97 previouslyWasOverlay = isOverlay; | |
| 98 | |
| 99 if (!invalidated || !scrollbar || graphicsLayer) | |
| 100 return; | 54 return; |
| 101 | 55 |
| 102 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*scrollbar,
PaintInvalidationScroll, &previousPaintInvalidationRect); | 56 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*scrollbar,
PaintInvalidationScroll, &previousPaintInvalidationRect); |
| 57 box.enclosingLayer()->setNeedsRepaint(); |
| 103 if (scrollbar->isCustomScrollbar()) | 58 if (scrollbar->isCustomScrollbar()) |
| 104 toLayoutScrollbar(scrollbar)->invalidateDisplayItemClientsOfScrollbarPar
ts(paintInvalidationContainer, previousPaintInvalidationRect); | 59 toLayoutScrollbar(scrollbar)->invalidateDisplayItemClientsOfScrollbarPar
ts(paintInvalidationContainer, previousPaintInvalidationRect); |
| 105 } | 60 } |
| 106 | 61 |
| 107 void PaintInvalidationCapableScrollableArea::invalidatePaintOfScrollControlsIfNe
eded(const PaintInvalidationState& paintInvalidationState, const LayoutBoxModelO
bject& paintInvalidationContainer) | 62 void PaintInvalidationCapableScrollableArea::invalidatePaintOfScrollControlsIfNe
eded(const PaintInvalidationState& paintInvalidationState, const LayoutBoxModelO
bject& paintInvalidationContainer) |
| 108 { | 63 { |
| 109 LayoutBox& box = boxForScrollControlPaintInvalidation(); | 64 LayoutBox& box = boxForScrollControlPaintInvalidation(); |
| 110 invalidatePaintOfScrollbarIfNeeded(horizontalScrollbar(), layerForHorizontal
Scrollbar(), m_horizontalScrollbarPreviouslyWasOverlay, m_horizontalScrollbarPre
viousPaintInvalidationRect, horizontalScrollbarNeedsPaintInvalidation(), box, pa
intInvalidationState, paintInvalidationContainer); | 65 LayoutRect oldRect = m_horizontalScrollbarPreviousPaintInvalidationRect; |
| 111 invalidatePaintOfScrollbarIfNeeded(verticalScrollbar(), layerForVerticalScro
llbar(), m_verticalScrollbarPreviouslyWasOverlay, m_verticalScrollbarPreviousPai
ntInvalidationRect, verticalScrollbarNeedsPaintInvalidation(), box, paintInvalid
ationState, paintInvalidationContainer); | 66 invalidatePaintOfScrollbarIfNeeded(horizontalScrollbar(), layerForHorizontal
Scrollbar(), m_horizontalScrollbarPreviousPaintInvalidationRect, horizontalScrol
lbarNeedsPaintInvalidation(), box, paintInvalidationState, paintInvalidationCont
ainer); |
| 67 bool scrollbarGeometryChanged = oldRect != m_horizontalScrollbarPreviousPain
tInvalidationRect; |
| 112 | 68 |
| 113 LayoutRect scrollCornerPaintInvalidationRect = scrollControlPaintInvalidatio
nRect(scrollCornerRect(), box, paintInvalidationState, paintInvalidationContaine
r); | 69 oldRect = m_verticalScrollbarPreviousPaintInvalidationRect; |
| 114 if (invalidatePaintOfScrollControlIfNeeded(scrollCornerPaintInvalidationRect
, m_scrollCornerPreviousPaintInvalidationRect, scrollCornerNeedsPaintInvalidatio
n(), box, paintInvalidationContainer)) { | 70 invalidatePaintOfScrollbarIfNeeded(verticalScrollbar(), layerForVerticalScro
llbar(), m_verticalScrollbarPreviousPaintInvalidationRect, verticalScrollbarNeed
sPaintInvalidation(), box, paintInvalidationState, paintInvalidationContainer); |
| 115 m_scrollCornerPreviousPaintInvalidationRect = scrollCornerPaintInvalidat
ionRect; | 71 scrollbarGeometryChanged |= oldRect != m_verticalScrollbarPreviousPaintInval
idationRect; |
| 72 |
| 73 if (scrollbarGeometryChanged) |
| 74 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(box, Pai
ntInvalidationScroll, nullptr); |
| 75 |
| 76 if (invalidatePaintOfScrollControlIfNeeded(scrollCornerRect(), m_scrollCorne
rPreviousPaintInvalidationRect, scrollCornerNeedsPaintInvalidation(), box, paint
InvalidationState, paintInvalidationContainer)) { |
| 116 if (LayoutScrollbarPart* scrollCorner = this->scrollCorner()) | 77 if (LayoutScrollbarPart* scrollCorner = this->scrollCorner()) |
| 117 scrollCorner->invalidateDisplayItemClientsIncludingNonCompositingDes
cendants(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPr
eviousPaintInvalidationRect); | 78 scrollCorner->invalidateDisplayItemClientsIncludingNonCompositingDes
cendants(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPr
eviousPaintInvalidationRect); |
| 118 if (LayoutScrollbarPart* resizer = this->resizer()) | 79 if (LayoutScrollbarPart* resizer = this->resizer()) |
| 119 resizer->invalidateDisplayItemClientsIncludingNonCompositingDescenda
nts(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPreviou
sPaintInvalidationRect); | 80 resizer->invalidateDisplayItemClientsIncludingNonCompositingDescenda
nts(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPreviou
sPaintInvalidationRect); |
| 120 } | 81 } |
| 121 | 82 |
| 122 clearNeedsPaintInvalidationForScrollControls(); | 83 clearNeedsPaintInvalidationForScrollControls(); |
| 123 } | 84 } |
| 124 | 85 |
| 125 void PaintInvalidationCapableScrollableArea::clearPreviousPaintInvalidationRects
() | |
| 126 { | |
| 127 m_horizontalScrollbarPreviousPaintInvalidationRect = LayoutRect(); | |
| 128 m_verticalScrollbarPreviousPaintInvalidationRect = LayoutRect(); | |
| 129 m_scrollCornerPreviousPaintInvalidationRect = LayoutRect(); | |
| 130 } | |
| 131 | |
| 132 } // namespace blink | 86 } // namespace blink |
| OLD | NEW |