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

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp

Issue 1491193003: Fix several corner case issues of scrollbar paint invalidation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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 // 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 static void invalidatePaintOfScrollbarIfNeeded(Scrollbar* scrollbar, GraphicsLay er* scrollbarGraphicsLayer, const LayoutRect& newPaintInvalidationRect, const La youtRect& previousPaintInvalidationRect, bool needsPaintInvalidation, LayoutBox& box, const LayoutBoxModelObject& paintInvalidationContainer)
49 { 52 {
50 IntRect scrollbarRect = scrollbar && !scrollbarGraphicsLayer ? scrollbar->fr ameRect() : IntRect(); 53 if (scrollbarGraphicsLayer && needsPaintInvalidation) {
51 if (!invalidatePaintOfScrollControlIfNeeded(scrollbarRect, previousPaintInva lidationRect, needsPaintInvalidation, box, paintInvalidationState, paintInvalida tionContainer)) 54 scrollbarGraphicsLayer->setNeedsDisplay();
55 scrollbarGraphicsLayer->setContentsNeedsDisplay();
56 // If the scrollbar needs paint invalidation but didn't change location/ size or the scrollbar is an
57 // overlay scrollbar (paint invalidation rect is empty), invalidating th e graphics layer is enough.
58 // Otherwise invalidatePaintOfScrollControlIfNeeded() below will invalid ate the old and new location
59 // of the scrollbar on the box's paint invalidation container to ensure newly expanded/shrunk areas
60 // of the box to be invalidated.
61 needsPaintInvalidation = false;
62 }
63
64 if (!invalidatePaintOfScrollControlIfNeeded(newPaintInvalidationRect, previo usPaintInvalidationRect, needsPaintInvalidation, box, paintInvalidationContainer ))
52 return; 65 return;
53 if (!scrollbar) 66
67 if (!scrollbar || scrollbarGraphicsLayer)
54 return; 68 return;
55 69
56 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*scrollbar, PaintInvalidationScroll, &previousPaintInvalidationRect); 70 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(*scrollbar, PaintInvalidationScroll, &previousPaintInvalidationRect);
57 box.enclosingLayer()->setNeedsRepaint();
58 if (scrollbar->isCustomScrollbar()) 71 if (scrollbar->isCustomScrollbar())
59 toLayoutScrollbar(scrollbar)->invalidateDisplayItemClientsOfScrollbarPar ts(paintInvalidationContainer, previousPaintInvalidationRect); 72 toLayoutScrollbar(scrollbar)->invalidateDisplayItemClientsOfScrollbarPar ts(paintInvalidationContainer, previousPaintInvalidationRect);
60 } 73 }
61 74
62 void PaintInvalidationCapableScrollableArea::invalidatePaintOfScrollControlsIfNe eded(const PaintInvalidationState& paintInvalidationState, const LayoutBoxModelO bject& paintInvalidationContainer) 75 void PaintInvalidationCapableScrollableArea::invalidatePaintOfScrollControlsIfNe eded(const PaintInvalidationState& paintInvalidationState, const LayoutBoxModelO bject& paintInvalidationContainer)
chrishtr 2015/12/03 18:52:36 There looks to be a lot of repeating code in this
Xianzhu 2015/12/03 22:13:27 Done.
63 { 76 {
64 LayoutBox& box = boxForScrollControlPaintInvalidation(); 77 LayoutBox& box = boxForScrollControlPaintInvalidation();
65 LayoutRect oldRect = m_horizontalScrollbarPreviousPaintInvalidationRect; 78 Scrollbar* horizontalScrollbar = this->horizontalScrollbar();
66 invalidatePaintOfScrollbarIfNeeded(horizontalScrollbar(), layerForHorizontal Scrollbar(), m_horizontalScrollbarPreviousPaintInvalidationRect, horizontalScrol lbarNeedsPaintInvalidation(), box, paintInvalidationState, paintInvalidationCont ainer); 79 Scrollbar* verticalScrollbar = this->verticalScrollbar();
67 bool scrollbarGeometryChanged = oldRect != m_horizontalScrollbarPreviousPain tInvalidationRect; 80 GraphicsLayer* layerForHorizontalScrollbar = this->layerForHorizontalScrollb ar();
81 GraphicsLayer* layerForVerticalScrollbar = this->layerForVerticalScrollbar() ;
82 bool horizontalScrollbarIsOverlay = horizontalScrollbar && horizontalScrollb ar->isOverlayScrollbar();
83 bool verticalScrollbarIsOverlay = verticalScrollbar && verticalScrollbar->is OverlayScrollbar();
68 84
69 oldRect = m_verticalScrollbarPreviousPaintInvalidationRect; 85 // Calculate paint invalidation rects of the scrollbars, except overlay comp osited scrollbars because we invalidate the graphics layer only.
70 invalidatePaintOfScrollbarIfNeeded(verticalScrollbar(), layerForVerticalScro llbar(), m_verticalScrollbarPreviousPaintInvalidationRect, verticalScrollbarNeed sPaintInvalidation(), box, paintInvalidationState, paintInvalidationContainer); 86 LayoutRect horizontalScrollbarPaintInvalidationRect;
71 scrollbarGeometryChanged |= oldRect != m_verticalScrollbarPreviousPaintInval idationRect; 87 if (horizontalScrollbar && !(layerForHorizontalScrollbar && horizontalScroll barIsOverlay))
88 horizontalScrollbarPaintInvalidationRect = scrollControlPaintInvalidatio nRect(horizontalScrollbar->frameRect(), box, paintInvalidationState, paintInvali dationContainer);
89 LayoutRect verticalScrollbarPaintInvalidationRect;
90 if (verticalScrollbar && !(layerForVerticalScrollbar && verticalScrollbarIsO verlay))
91 verticalScrollbarPaintInvalidationRect = scrollControlPaintInvalidationR ect(verticalScrollbar->frameRect(), box, paintInvalidationState, paintInvalidati onContainer);
72 92
73 if (scrollbarGeometryChanged) 93 invalidatePaintOfScrollbarIfNeeded(horizontalScrollbar, layerForHorizontalSc rollbar, horizontalScrollbarPaintInvalidationRect, m_horizontalScrollbarPrevious PaintInvalidationRect, horizontalScrollbarNeedsPaintInvalidation(), box, paintIn validationContainer);
94 invalidatePaintOfScrollbarIfNeeded(verticalScrollbar, layerForVerticalScroll bar, verticalScrollbarPaintInvalidationRect, m_verticalScrollbarPreviousPaintInv alidationRect, verticalScrollbarNeedsPaintInvalidation(), box, paintInvalidation Container);
95
96 // Invalidate the box's display item client if the box's padding box size is affected by change of non-overlay scrollbar widths.
97 LayoutSize horizontalScrollbarSize = horizontalScrollbarIsOverlay ? LayoutSi ze() : horizontalScrollbarPaintInvalidationRect.size();
98 LayoutSize verticalScrollbarSize = verticalScrollbarIsOverlay ? LayoutSize() : verticalScrollbarPaintInvalidationRect.size();
99 LayoutSize horizontalScrollbarPreviousSize = m_horizontalScrollbarPreviously WasOverlay ? LayoutSize() : m_horizontalScrollbarPreviousPaintInvalidationRect.s ize();
100 LayoutSize verticalScrollbarPreviousSize = m_verticalScrollbarPreviouslyWasO verlay ? LayoutSize() : m_verticalScrollbarPreviousPaintInvalidationRect.size();
101 if (horizontalScrollbarSize != horizontalScrollbarPreviousSize || verticalSc rollbarSize != verticalScrollbarPreviousSize)
74 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(box, Pai ntInvalidationScroll, nullptr); 102 paintInvalidationContainer.invalidateDisplayItemClientOnBacking(box, Pai ntInvalidationScroll, nullptr);
75 103
76 if (invalidatePaintOfScrollControlIfNeeded(scrollCornerRect(), m_scrollCorne rPreviousPaintInvalidationRect, scrollCornerNeedsPaintInvalidation(), box, paint InvalidationState, paintInvalidationContainer)) { 104 m_horizontalScrollbarPreviousPaintInvalidationRect = horizontalScrollbarPain tInvalidationRect;
105 m_horizontalScrollbarPreviouslyWasOverlay = horizontalScrollbarIsOverlay;
106 m_verticalScrollbarPreviousPaintInvalidationRect = verticalScrollbarPaintInv alidationRect;
107 m_verticalScrollbarPreviouslyWasOverlay = verticalScrollbarIsOverlay;
108
109 LayoutRect scrollCornerPaintInvalidationRect = scrollControlPaintInvalidatio nRect(scrollCornerRect(), box, paintInvalidationState, paintInvalidationContaine r);
110 if (invalidatePaintOfScrollControlIfNeeded(scrollCornerPaintInvalidationRect , m_scrollCornerPreviousPaintInvalidationRect, scrollCornerNeedsPaintInvalidatio n(), box, paintInvalidationContainer)) {
111 m_scrollCornerPreviousPaintInvalidationRect = scrollCornerPaintInvalidat ionRect;
77 if (LayoutScrollbarPart* scrollCorner = this->scrollCorner()) 112 if (LayoutScrollbarPart* scrollCorner = this->scrollCorner())
78 scrollCorner->invalidateDisplayItemClientsIncludingNonCompositingDes cendants(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPr eviousPaintInvalidationRect); 113 scrollCorner->invalidateDisplayItemClientsIncludingNonCompositingDes cendants(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPr eviousPaintInvalidationRect);
79 if (LayoutScrollbarPart* resizer = this->resizer()) 114 if (LayoutScrollbarPart* resizer = this->resizer())
80 resizer->invalidateDisplayItemClientsIncludingNonCompositingDescenda nts(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPreviou sPaintInvalidationRect); 115 resizer->invalidateDisplayItemClientsIncludingNonCompositingDescenda nts(&paintInvalidationContainer, PaintInvalidationScroll, &m_scrollCornerPreviou sPaintInvalidationRect);
81 } 116 }
82 117
83 clearNeedsPaintInvalidationForScrollControls(); 118 clearNeedsPaintInvalidationForScrollControls();
84 } 119 }
85 120
121 void PaintInvalidationCapableScrollableArea::clearPreviousPaintInvalidationRects ()
122 {
123 m_horizontalScrollbarPreviousPaintInvalidationRect = LayoutRect();
124 m_verticalScrollbarPreviousPaintInvalidationRect = LayoutRect();
125 m_scrollCornerPreviousPaintInvalidationRect = LayoutRect();
126 }
127
86 } // namespace blink 128 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698