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" | |
15 | 16 |
16 namespace blink { | 17 namespace blink { |
17 | 18 |
18 void PaintInvalidationCapableScrollableArea::willRemoveScrollbar(Scrollbar* scro llbar, ScrollbarOrientation orientation) | 19 void PaintInvalidationCapableScrollableArea::willRemoveScrollbar(Scrollbar* scro llbar, ScrollbarOrientation orientation) |
19 { | 20 { |
20 if (!scrollbar->isCustomScrollbar() | 21 if (!scrollbar->isCustomScrollbar() |
21 && !(orientation == HorizontalScrollbar ? layerForHorizontalScrollbar() : layerForVerticalScrollbar())) | 22 && !(orientation == HorizontalScrollbar ? layerForHorizontalScrollbar() : layerForVerticalScrollbar())) |
22 boxForScrollControlPaintInvalidation().invalidateDisplayItemClient(*scro llbar); | 23 boxForScrollControlPaintInvalidation().invalidateDisplayItemClient(*scro llbar); |
23 | 24 |
24 ScrollableArea::willRemoveScrollbar(scrollbar, orientation); | 25 ScrollableArea::willRemoveScrollbar(scrollbar, orientation); |
25 } | 26 } |
26 | 27 |
27 // Returns true if the scroll control is invalidated. | 28 static LayoutRect scrollControlPaintInvalidationRect(const IntRect& scrollContro lRect, const LayoutBox& box, const PaintInvalidationState& paintInvalidationStat e, const LayoutBoxModelObject& paintInvalidationContainer) |
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 } | |
33 | 35 |
34 if (paintInvalidationRect != previousPaintInvalidationRect) { | 36 // Returns true if the scroll control is invalidated. |
37 static bool invalidatePaintOfScrollControlIfNeeded(const LayoutRect& newPaintInv alidationRect, const LayoutRect& previousPaintInvalidationRect, bool needsPaintI nvalidation, LayoutBox& box, const LayoutBoxModelObject& paintInvalidationContai ner) | |
38 { | |
39 if (newPaintInvalidationRect != previousPaintInvalidationRect) { | |
35 box.invalidatePaintUsingContainer(paintInvalidationContainer, previousPa intInvalidationRect, PaintInvalidationScroll); | 40 box.invalidatePaintUsingContainer(paintInvalidationContainer, previousPa intInvalidationRect, PaintInvalidationScroll); |
36 previousPaintInvalidationRect = paintInvalidationRect; | |
37 needsPaintInvalidation = true; | 41 needsPaintInvalidation = true; |
38 } | 42 } |
39 | |
40 if (needsPaintInvalidation) { | 43 if (needsPaintInvalidation) { |
41 box.invalidatePaintUsingContainer(paintInvalidationContainer, paintInval idationRect, PaintInvalidationScroll); | 44 box.invalidatePaintUsingContainer(paintInvalidationContainer, newPaintIn validationRect, PaintInvalidationScroll); |
45 box.enclosingLayer()->setNeedsRepaint(); | |
42 return true; | 46 return true; |
43 } | 47 } |
44 | |
45 return false; | 48 return false; |
46 } | 49 } |
47 | 50 |
48 static void invalidatePaintOfScrollbarIfNeeded(Scrollbar* scrollbar, GraphicsLay er* scrollbarGraphicsLayer, LayoutRect& previousPaintInvalidationRect, bool need sPaintInvalidation, LayoutBox& box, const PaintInvalidationState& paintInvalidat ionState, const LayoutBoxModelObject& paintInvalidationContainer) | 51 struct ScrollbarPaintInvalidationData { |
52 Scrollbar* scrollbar; | |
53 GraphicsLayer* graphicsLayer; | |
54 LayoutRect& previousPaintInvalidatioRect; | |
55 | |
56 }; | |
57 | |
58 static void invalidatePaintOfScrollbarIfNeeded(Scrollbar* scrollbar, GraphicsLay er* graphicsLayer, bool& previouslyWasOverlay, LayoutRect& previousPaintInvalida tionRect, bool needsPaintInvalidation, LayoutBox& box, const PaintInvalidationSt ate& paintInvalidationState, const LayoutBoxModelObject& paintInvalidationContai ner) | |
49 { | 59 { |
50 IntRect scrollbarRect = scrollbar && !scrollbarGraphicsLayer ? scrollbar->fr ameRect() : IntRect(); | 60 bool isOverlay = scrollbar && scrollbar->isOverlayScrollbar(); |
51 if (!invalidatePaintOfScrollControlIfNeeded(scrollbarRect, previousPaintInva lidationRect, needsPaintInvalidation, box, paintInvalidationState, paintInvalida tionContainer)) | 61 |
52 return; | 62 // Calculate paint invalidation rect of the scrollbar, except overlay compos ited scrollbars because we invalidate the graphics layer only. |
53 if (!scrollbar) | 63 LayoutRect newPaintInvalidationRect; |
64 if (scrollbar && !(graphicsLayer && isOverlay)) | |
65 newPaintInvalidationRect = scrollControlPaintInvalidationRect(scrollbar- >frameRect(), box, paintInvalidationState, paintInvalidationContainer); | |
66 | |
67 if (graphicsLayer && needsPaintInvalidation) { | |
68 graphicsLayer->setNeedsDisplay(); | |
69 graphicsLayer->setContentsNeedsDisplay(); | |
70 // If the scrollbar needs paint invalidation but didn't change location/ size or the scrollbar is an | |
71 // overlay scrollbar (paint invalidation rect is empty), invalidating th e graphics layer is enough. | |
72 // Otherwise invalidatePaintOfScrollControlIfNeeded() below will invalid ate the old and new location | |
73 // of the scrollbar on the box's paint invalidation container to ensure newly expanded/shrunk areas | |
74 // of the box to be invalidated. | |
75 needsPaintInvalidation = false; | |
chrishtr
2015/12/04 00:20:01
I find overriding a parameter's value a confusing
Xianzhu
2015/12/04 01:08:36
Done (needsPaintInvalidationArg and needsPaintInva
| |
76 } | |
77 | |
78 // Invalidate the box's display item client if the box's padding box size is affected by change of the | |
79 // non-overlay scrollbar width. We detect change of paint invalidation rect size instead of change of | |
80 // scrollbar width change, which may have some false-positives (e.g. the scr ollbar changed length but | |
81 // not width) but won't invalidate more than expected because in the false-p ositive case the box must | |
82 // have changed size and have been invalidated. | |
83 LayoutSize newNonOverlaySize = isOverlay ? LayoutSize() : newPaintInvalidati onRect.size(); | |
chrishtr
2015/12/04 00:20:00
It's weird to set a "newNonOverlaySize" variable i
Xianzhu
2015/12/04 01:08:36
Changed to
if (!isOverlay)
newNonOverlaySize = .
| |
84 LayoutSize previousNonOverlaySize = previouslyWasOverlay ? LayoutSize() : pr eviousPaintInvalidationRect.size(); | |
85 if (newNonOverlaySize != previousNonOverlaySize) | |
86 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(box, Pai ntInvalidationScroll, nullptr); | |
87 | |
88 bool invalidated = invalidatePaintOfScrollControlIfNeeded(newPaintInvalidati onRect, previousPaintInvalidationRect, needsPaintInvalidation, box, paintInvalid ationContainer); | |
89 | |
90 previousPaintInvalidationRect = newPaintInvalidationRect; | |
91 previouslyWasOverlay = isOverlay; | |
92 | |
93 if (!invalidated || !scrollbar || graphicsLayer) | |
54 return; | 94 return; |
55 | 95 |
56 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*scrollbar, PaintInvalidationScroll, &previousPaintInvalidationRect); | 96 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*scrollbar, PaintInvalidationScroll, &previousPaintInvalidationRect); |
57 box.enclosingLayer()->setNeedsRepaint(); | |
58 if (scrollbar->isCustomScrollbar()) | 97 if (scrollbar->isCustomScrollbar()) |
59 toLayoutScrollbar(scrollbar)->invalidateDisplayItemClientsOfScrollbarPar ts(paintInvalidationContainer, previousPaintInvalidationRect); | 98 toLayoutScrollbar(scrollbar)->invalidateDisplayItemClientsOfScrollbarPar ts(paintInvalidationContainer, previousPaintInvalidationRect); |
60 } | 99 } |
61 | 100 |
62 void PaintInvalidationCapableScrollableArea::invalidatePaintOfScrollControlsIfNe eded(const PaintInvalidationState& paintInvalidationState, const LayoutBoxModelO bject& paintInvalidationContainer) | 101 void PaintInvalidationCapableScrollableArea::invalidatePaintOfScrollControlsIfNe eded(const PaintInvalidationState& paintInvalidationState, const LayoutBoxModelO bject& paintInvalidationContainer) |
63 { | 102 { |
64 LayoutBox& box = boxForScrollControlPaintInvalidation(); | 103 LayoutBox& box = boxForScrollControlPaintInvalidation(); |
65 LayoutRect oldRect = m_horizontalScrollbarPreviousPaintInvalidationRect; | 104 invalidatePaintOfScrollbarIfNeeded(horizontalScrollbar(), layerForHorizontal Scrollbar(), m_horizontalScrollbarPreviouslyWasOverlay, m_horizontalScrollbarPre viousPaintInvalidationRect, horizontalScrollbarNeedsPaintInvalidation(), box, pa intInvalidationState, paintInvalidationContainer); |
66 invalidatePaintOfScrollbarIfNeeded(horizontalScrollbar(), layerForHorizontal Scrollbar(), m_horizontalScrollbarPreviousPaintInvalidationRect, horizontalScrol lbarNeedsPaintInvalidation(), box, paintInvalidationState, paintInvalidationCont ainer); | 105 invalidatePaintOfScrollbarIfNeeded(verticalScrollbar(), layerForVerticalScro llbar(), m_verticalScrollbarPreviouslyWasOverlay, m_verticalScrollbarPreviousPai ntInvalidationRect, verticalScrollbarNeedsPaintInvalidation(), box, paintInvalid ationState, paintInvalidationContainer); |
67 bool scrollbarGeometryChanged = oldRect != m_horizontalScrollbarPreviousPain tInvalidationRect; | |
68 | 106 |
69 oldRect = m_verticalScrollbarPreviousPaintInvalidationRect; | 107 LayoutRect scrollCornerPaintInvalidationRect = scrollControlPaintInvalidatio nRect(scrollCornerRect(), box, paintInvalidationState, paintInvalidationContaine r); |
70 invalidatePaintOfScrollbarIfNeeded(verticalScrollbar(), layerForVerticalScro llbar(), m_verticalScrollbarPreviousPaintInvalidationRect, verticalScrollbarNeed sPaintInvalidation(), box, paintInvalidationState, paintInvalidationContainer); | 108 if (invalidatePaintOfScrollControlIfNeeded(scrollCornerPaintInvalidationRect , m_scrollCornerPreviousPaintInvalidationRect, scrollCornerNeedsPaintInvalidatio n(), box, paintInvalidationContainer)) { |
71 scrollbarGeometryChanged |= oldRect != m_verticalScrollbarPreviousPaintInval idationRect; | 109 m_scrollCornerPreviousPaintInvalidationRect = scrollCornerPaintInvalidat ionRect; |
72 | |
73 if (scrollbarGeometryChanged) | |
74 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(box, Pai ntInvalidationScroll, nullptr); | |
75 | |
76 if (invalidatePaintOfScrollControlIfNeeded(scrollCornerRect(), m_scrollCorne rPreviousPaintInvalidationRect, scrollCornerNeedsPaintInvalidation(), box, paint InvalidationState, paintInvalidationContainer)) { | |
77 if (LayoutScrollbarPart* scrollCorner = this->scrollCorner()) | 110 if (LayoutScrollbarPart* scrollCorner = this->scrollCorner()) |
78 scrollCorner->invalidateDisplayItemClientsIncludingNonCompositingDes cendants(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPr eviousPaintInvalidationRect); | 111 scrollCorner->invalidateDisplayItemClientsIncludingNonCompositingDes cendants(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPr eviousPaintInvalidationRect); |
79 if (LayoutScrollbarPart* resizer = this->resizer()) | 112 if (LayoutScrollbarPart* resizer = this->resizer()) |
80 resizer->invalidateDisplayItemClientsIncludingNonCompositingDescenda nts(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPreviou sPaintInvalidationRect); | 113 resizer->invalidateDisplayItemClientsIncludingNonCompositingDescenda nts(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPreviou sPaintInvalidationRect); |
81 } | 114 } |
82 | 115 |
83 clearNeedsPaintInvalidationForScrollControls(); | 116 clearNeedsPaintInvalidationForScrollControls(); |
84 } | 117 } |
85 | 118 |
119 void PaintInvalidationCapableScrollableArea::clearPreviousPaintInvalidationRects () | |
120 { | |
121 m_horizontalScrollbarPreviousPaintInvalidationRect = LayoutRect(); | |
122 m_verticalScrollbarPreviousPaintInvalidationRect = LayoutRect(); | |
123 m_scrollCornerPreviousPaintInvalidationRect = LayoutRect(); | |
124 } | |
125 | |
86 } // namespace blink | 126 } // namespace blink |
OLD | NEW |