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

Side by Side Diff: third_party/WebKit/Source/platform/scroll/ScrollableAreaTest.cpp

Issue 1591953005: Make ScrollbarThemeAura selectively invalidate scrollbar parts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge with master; remove blank line Created 4 years, 11 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 // 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 "platform/scroll/ScrollableArea.h" 5 #include "platform/scroll/ScrollableArea.h"
6 6
7 #include "platform/graphics/GraphicsLayer.h" 7 #include "platform/graphics/GraphicsLayer.h"
8 #include "platform/scroll/ScrollbarTheme.h" 8 #include "platform/scroll/ScrollbarTheme.h"
9 #include "platform/scroll/ScrollbarThemeMock.h" 9 #include "platform/scroll/ScrollbarThemeMock.h"
10 #include "platform/testing/TestingPlatformSupport.h" 10 #include "platform/testing/TestingPlatformSupport.h"
11 #include "public/platform/Platform.h" 11 #include "public/platform/Platform.h"
12 #include "testing/gmock/include/gmock/gmock.h" 12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
14 14
15 namespace blink { 15 namespace blink {
16 16
17 namespace { 17 namespace {
18 18
19 using testing::_;
19 using testing::Return; 20 using testing::Return;
20 21
21 class MockScrollableArea : public NoBaseWillBeGarbageCollectedFinalized<MockScro llableArea>, public ScrollableArea { 22 class MockScrollableArea : public NoBaseWillBeGarbageCollectedFinalized<MockScro llableArea>, public ScrollableArea {
22 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MockScrollableArea); 23 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MockScrollableArea);
23 public: 24 public:
24 static PassOwnPtrWillBeRawPtr<MockScrollableArea> create(const IntPoint& max imumScrollPosition) 25 static PassOwnPtrWillBeRawPtr<MockScrollableArea> create(const IntPoint& max imumScrollPosition)
25 { 26 {
26 return adoptPtrWillBeNoop(new MockScrollableArea(maximumScrollPosition)) ; 27 return adoptPtrWillBeNoop(new MockScrollableArea(maximumScrollPosition)) ;
27 } 28 }
28 29
29 MOCK_CONST_METHOD0(isActive, bool()); 30 MOCK_CONST_METHOD0(isActive, bool());
30 MOCK_CONST_METHOD1(scrollSize, int(ScrollbarOrientation)); 31 MOCK_CONST_METHOD1(scrollSize, int(ScrollbarOrientation));
31 MOCK_CONST_METHOD0(isScrollCornerVisible, bool()); 32 MOCK_CONST_METHOD0(isScrollCornerVisible, bool());
32 MOCK_CONST_METHOD0(scrollCornerRect, IntRect()); 33 MOCK_CONST_METHOD0(scrollCornerRect, IntRect());
34 MOCK_CONST_METHOD0(horizontalScrollbar, Scrollbar*());
35 MOCK_CONST_METHOD0(verticalScrollbar, Scrollbar*());
33 MOCK_METHOD0(scrollControlWasSetNeedsPaintInvalidation, void()); 36 MOCK_METHOD0(scrollControlWasSetNeedsPaintInvalidation, void());
34 MOCK_CONST_METHOD0(enclosingScrollableArea, ScrollableArea*()); 37 MOCK_CONST_METHOD0(enclosingScrollableArea, ScrollableArea*());
35 MOCK_CONST_METHOD1(visibleContentRect, IntRect(IncludeScrollbarsInRect)); 38 MOCK_CONST_METHOD1(visibleContentRect, IntRect(IncludeScrollbarsInRect));
36 MOCK_CONST_METHOD0(contentsSize, IntSize()); 39 MOCK_CONST_METHOD0(contentsSize, IntSize());
37 MOCK_CONST_METHOD0(scrollableAreaBoundingBox, IntRect()); 40 MOCK_CONST_METHOD0(scrollableAreaBoundingBox, IntRect());
38 MOCK_CONST_METHOD0(layerForHorizontalScrollbar, GraphicsLayer*()); 41 MOCK_CONST_METHOD0(layerForHorizontalScrollbar, GraphicsLayer*());
42 MOCK_CONST_METHOD0(layerForVerticalScrollbar, GraphicsLayer*());
39 43
40 bool userInputScrollable(ScrollbarOrientation) const override { return true; } 44 bool userInputScrollable(ScrollbarOrientation) const override { return true; }
41 bool scrollbarsCanBeActive () const override { return true; } 45 bool scrollbarsCanBeActive () const override { return true; }
42 bool shouldPlaceVerticalScrollbarOnLeft() const override { return false; } 46 bool shouldPlaceVerticalScrollbarOnLeft() const override { return false; }
43 void setScrollOffset(const IntPoint& offset, ScrollType) override { m_scroll Position = offset.shrunkTo(m_maximumScrollPosition); } 47 void setScrollOffset(const IntPoint& offset, ScrollType) override { m_scroll Position = offset.shrunkTo(m_maximumScrollPosition); }
44 IntPoint scrollPosition() const override { return m_scrollPosition; } 48 IntPoint scrollPosition() const override { return m_scrollPosition; }
45 IntPoint minimumScrollPosition() const override { return IntPoint(); } 49 IntPoint minimumScrollPosition() const override { return IntPoint(); }
46 IntPoint maximumScrollPosition() const override { return m_maximumScrollPosi tion; } 50 IntPoint maximumScrollPosition() const override { return m_maximumScrollPosi tion; }
47 int visibleHeight() const override { return 768; } 51 int visibleHeight() const override { return 768; }
48 int visibleWidth() const override { return 1024; } 52 int visibleWidth() const override { return 1024; }
49 bool scrollAnimatorEnabled() const override { return false; } 53 bool scrollAnimatorEnabled() const override { return false; }
50 int pageStep(ScrollbarOrientation) const override { return 0; } 54 int pageStep(ScrollbarOrientation) const override { return 0; }
51 55
56 using ScrollableArea::horizontalScrollbarNeedsPaintInvalidation;
57 using ScrollableArea::verticalScrollbarNeedsPaintInvalidation;
58 using ScrollableArea::clearNeedsPaintInvalidationForScrollControls;
59
52 DEFINE_INLINE_VIRTUAL_TRACE() 60 DEFINE_INLINE_VIRTUAL_TRACE()
53 { 61 {
54 ScrollableArea::trace(visitor); 62 ScrollableArea::trace(visitor);
55 } 63 }
56 64
57 private: 65 private:
58 explicit MockScrollableArea(const IntPoint& maximumScrollPosition) 66 explicit MockScrollableArea(const IntPoint& maximumScrollPosition)
59 : m_maximumScrollPosition(maximumScrollPosition) { } 67 : m_maximumScrollPosition(maximumScrollPosition) { }
60 68
61 IntPoint m_scrollPosition; 69 IntPoint m_scrollPosition;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea:: create(IntPoint(0, 100)); 101 OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea:: create(IntPoint(0, 100));
94 scrollableArea->setScrollPosition(IntPoint(0, 10000), CompositorScroll); 102 scrollableArea->setScrollPosition(IntPoint(0, 10000), CompositorScroll);
95 EXPECT_EQ(100.0, scrollableArea->scrollAnimator().currentPosition().y()); 103 EXPECT_EQ(100.0, scrollableArea->scrollAnimator().currentPosition().y());
96 } 104 }
97 105
98 namespace { 106 namespace {
99 107
100 class ScrollbarThemeWithMockInvalidation : public ScrollbarThemeMock { 108 class ScrollbarThemeWithMockInvalidation : public ScrollbarThemeMock {
101 public: 109 public:
102 MOCK_CONST_METHOD0(shouldRepaintAllPartsOnInvalidation, bool()); 110 MOCK_CONST_METHOD0(shouldRepaintAllPartsOnInvalidation, bool());
111 MOCK_CONST_METHOD3(invalidateOnThumbPositionChange, ScrollbarPart(const Scro llbarThemeClient&, float, float));
103 }; 112 };
104 113
105 } // namespace 114 } // namespace
106 115
107 TEST_F(ScrollableAreaTest, ScrollbarTrackAndThumbRepaint) 116 TEST_F(ScrollableAreaTest, ScrollbarTrackAndThumbRepaint)
108 { 117 {
109 ScrollbarThemeWithMockInvalidation theme; 118 ScrollbarThemeWithMockInvalidation theme;
110 OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea:: create(IntPoint(0, 100)); 119 OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea:: create(IntPoint(0, 100));
111 RefPtrWillBeRawPtr<Scrollbar> scrollbar = Scrollbar::createForTesting(scroll ableArea.get(), HorizontalScrollbar, RegularScrollbar, &theme); 120 RefPtrWillBeRawPtr<Scrollbar> scrollbar = Scrollbar::createForTesting(scroll ableArea.get(), HorizontalScrollbar, RegularScrollbar, &theme);
112 121
113 EXPECT_CALL(theme, shouldRepaintAllPartsOnInvalidation()).WillRepeatedly(Ret urn(true)); 122 EXPECT_CALL(theme, shouldRepaintAllPartsOnInvalidation()).WillRepeatedly(Ret urn(true));
114 EXPECT_TRUE(scrollbar->trackNeedsRepaint()); 123 EXPECT_TRUE(scrollbar->trackNeedsRepaint());
115 EXPECT_TRUE(scrollbar->thumbNeedsRepaint()); 124 EXPECT_TRUE(scrollbar->thumbNeedsRepaint());
116 scrollbar->setNeedsPaintInvalidation(NoPart); 125 scrollbar->setNeedsPaintInvalidation(NoPart);
117 EXPECT_TRUE(scrollbar->trackNeedsRepaint()); 126 EXPECT_TRUE(scrollbar->trackNeedsRepaint());
118 EXPECT_TRUE(scrollbar->thumbNeedsRepaint()); 127 EXPECT_TRUE(scrollbar->thumbNeedsRepaint());
119 128
120 scrollbar->clearTrackNeedsRepaint(); 129 scrollbar->clearTrackNeedsRepaint();
121 scrollbar->clearThumbNeedsRepaint(); 130 scrollbar->clearThumbNeedsRepaint();
122 EXPECT_FALSE(scrollbar->trackNeedsRepaint()); 131 EXPECT_FALSE(scrollbar->trackNeedsRepaint());
123 EXPECT_FALSE(scrollbar->thumbNeedsRepaint()); 132 EXPECT_FALSE(scrollbar->thumbNeedsRepaint());
124 scrollbar->setNeedsPaintInvalidation(NoPart); 133 scrollbar->setNeedsPaintInvalidation(ThumbPart);
125 EXPECT_TRUE(scrollbar->trackNeedsRepaint()); 134 EXPECT_TRUE(scrollbar->trackNeedsRepaint());
126 EXPECT_TRUE(scrollbar->thumbNeedsRepaint()); 135 EXPECT_TRUE(scrollbar->thumbNeedsRepaint());
127 136
137 // When not all parts are repainted on invalidation,
138 // setNeedsPaintInvalidation sets repaint bits only on the requested parts.
128 EXPECT_CALL(theme, shouldRepaintAllPartsOnInvalidation()).WillRepeatedly(Ret urn(false)); 139 EXPECT_CALL(theme, shouldRepaintAllPartsOnInvalidation()).WillRepeatedly(Ret urn(false));
129 scrollbar->clearTrackNeedsRepaint(); 140 scrollbar->clearTrackNeedsRepaint();
130 scrollbar->clearThumbNeedsRepaint(); 141 scrollbar->clearThumbNeedsRepaint();
131 EXPECT_FALSE(scrollbar->trackNeedsRepaint()); 142 EXPECT_FALSE(scrollbar->trackNeedsRepaint());
132 EXPECT_FALSE(scrollbar->thumbNeedsRepaint()); 143 EXPECT_FALSE(scrollbar->thumbNeedsRepaint());
133 scrollbar->setNeedsPaintInvalidation(NoPart); 144 scrollbar->setNeedsPaintInvalidation(ThumbPart);
134 EXPECT_FALSE(scrollbar->trackNeedsRepaint()); 145 EXPECT_FALSE(scrollbar->trackNeedsRepaint());
135 EXPECT_FALSE(scrollbar->thumbNeedsRepaint()); 146 EXPECT_TRUE(scrollbar->thumbNeedsRepaint());
136 147
137 // Forced GC in order to finalize objects depending on the mock object. 148 // Forced GC in order to finalize objects depending on the mock object.
138 Heap::collectAllGarbage(); 149 Heap::collectAllGarbage();
139 } 150 }
140 151
141 class MockGraphicsLayerClient : public GraphicsLayerClient { 152 class MockGraphicsLayerClient : public GraphicsLayerClient {
142 public: 153 public:
143 IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const { re turn IntRect(); } 154 IntRect computeInterestRect(const GraphicsLayer*, const IntRect&) const { re turn IntRect(); }
144 void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPain tingPhase, const IntRect&) const override { } 155 void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPain tingPhase, const IntRect&) const override { }
145 String debugName(const GraphicsLayer*) const override { return String(); } 156 String debugName(const GraphicsLayer*) const override { return String(); }
(...skipping 15 matching lines...) Expand all
161 graphicsLayer.setSize(FloatSize(111, 222)); 172 graphicsLayer.setSize(FloatSize(111, 222));
162 173
163 EXPECT_CALL(*scrollableArea, layerForHorizontalScrollbar()).WillRepeatedly(R eturn(&graphicsLayer)); 174 EXPECT_CALL(*scrollableArea, layerForHorizontalScrollbar()).WillRepeatedly(R eturn(&graphicsLayer));
164 175
165 RefPtrWillBeRawPtr<Scrollbar> scrollbar = Scrollbar::create(scrollableArea.g et(), HorizontalScrollbar, RegularScrollbar, nullptr); 176 RefPtrWillBeRawPtr<Scrollbar> scrollbar = Scrollbar::create(scrollableArea.g et(), HorizontalScrollbar, RegularScrollbar, nullptr);
166 graphicsLayer.resetTrackedPaintInvalidations(); 177 graphicsLayer.resetTrackedPaintInvalidations();
167 scrollbar->setNeedsPaintInvalidation(NoPart); 178 scrollbar->setNeedsPaintInvalidation(NoPart);
168 EXPECT_TRUE(graphicsLayer.hasTrackedPaintInvalidations()); 179 EXPECT_TRUE(graphicsLayer.hasTrackedPaintInvalidations());
169 } 180 }
170 181
182 TEST_F(ScrollableAreaTest, InvalidatesNonCompositedScrollbarsWhenThumbMoves)
183 {
184 ScrollbarThemeWithMockInvalidation theme;
185 OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea:: create(IntPoint(100, 100));
186 RefPtrWillBeRawPtr<Scrollbar> horizontalScrollbar = Scrollbar::createForTest ing(scrollableArea.get(), HorizontalScrollbar, RegularScrollbar, &theme);
187 RefPtrWillBeRawPtr<Scrollbar> verticalScrollbar = Scrollbar::createForTestin g(scrollableArea.get(), VerticalScrollbar, RegularScrollbar, &theme);
188 EXPECT_CALL(*scrollableArea, horizontalScrollbar()).WillRepeatedly(Return(ho rizontalScrollbar.get()));
189 EXPECT_CALL(*scrollableArea, verticalScrollbar()).WillRepeatedly(Return(vert icalScrollbar.get()));
190
191 // Regardless of whether the theme invalidates any parts, non-composited
192 // scrollbars have to be repainted if the thumb moves.
193 EXPECT_CALL(*scrollableArea, layerForHorizontalScrollbar()).WillRepeatedly(R eturn(nullptr));
194 EXPECT_CALL(*scrollableArea, layerForVerticalScrollbar()).WillRepeatedly(Ret urn(nullptr));
195 ASSERT_FALSE(scrollableArea->hasLayerForVerticalScrollbar());
196 ASSERT_FALSE(scrollableArea->hasLayerForHorizontalScrollbar());
197 EXPECT_CALL(theme, shouldRepaintAllPartsOnInvalidation()).WillRepeatedly(Ret urn(false));
198 EXPECT_CALL(theme, invalidateOnThumbPositionChange(_, _, _)).WillRepeatedly( Return(NoPart));
199
200 // A scroll in each direction should only invalidate one scrollbar.
201 scrollableArea->setScrollPosition(DoublePoint(0, 50), ProgrammaticScroll);
202 EXPECT_FALSE(scrollableArea->horizontalScrollbarNeedsPaintInvalidation());
203 EXPECT_TRUE(scrollableArea->verticalScrollbarNeedsPaintInvalidation());
204 scrollableArea->clearNeedsPaintInvalidationForScrollControls();
205 scrollableArea->setScrollPosition(DoublePoint(50, 50), ProgrammaticScroll);
206 EXPECT_TRUE(scrollableArea->horizontalScrollbarNeedsPaintInvalidation());
207 EXPECT_FALSE(scrollableArea->verticalScrollbarNeedsPaintInvalidation());
208 scrollableArea->clearNeedsPaintInvalidationForScrollControls();
209
210 // Forced GC in order to finalize objects depending on the mock object.
211 Heap::collectAllGarbage();
212 }
213
214 TEST_F(ScrollableAreaTest, InvalidatesCompositedScrollbarsIfPartsNeedRepaint)
215 {
216 ScrollbarThemeWithMockInvalidation theme;
217 OwnPtrWillBeRawPtr<MockScrollableArea> scrollableArea = MockScrollableArea:: create(IntPoint(100, 100));
218 RefPtrWillBeRawPtr<Scrollbar> horizontalScrollbar = Scrollbar::createForTest ing(scrollableArea.get(), HorizontalScrollbar, RegularScrollbar, &theme);
219 horizontalScrollbar->clearTrackNeedsRepaint();
220 horizontalScrollbar->clearThumbNeedsRepaint();
221 RefPtrWillBeRawPtr<Scrollbar> verticalScrollbar = Scrollbar::createForTestin g(scrollableArea.get(), VerticalScrollbar, RegularScrollbar, &theme);
222 verticalScrollbar->clearTrackNeedsRepaint();
223 verticalScrollbar->clearThumbNeedsRepaint();
224 EXPECT_CALL(*scrollableArea, horizontalScrollbar()).WillRepeatedly(Return(ho rizontalScrollbar.get()));
225 EXPECT_CALL(*scrollableArea, verticalScrollbar()).WillRepeatedly(Return(vert icalScrollbar.get()));
226
227 // Composited scrollbars only need repainting when parts become invalid
228 // (e.g. if the track changes appearance when the thumb reaches the end).
229 MockGraphicsLayerClient graphicsLayerClient;
230 MockGraphicsLayer layerForHorizontalScrollbar(&graphicsLayerClient);
231 layerForHorizontalScrollbar.setDrawsContent(true);
232 layerForHorizontalScrollbar.setSize(FloatSize(10, 10));
233 MockGraphicsLayer layerForVerticalScrollbar(&graphicsLayerClient);
234 layerForVerticalScrollbar.setDrawsContent(true);
235 layerForVerticalScrollbar.setSize(FloatSize(10, 10));
236 EXPECT_CALL(*scrollableArea, layerForHorizontalScrollbar()).WillRepeatedly(R eturn(&layerForHorizontalScrollbar));
237 EXPECT_CALL(*scrollableArea, layerForVerticalScrollbar()).WillRepeatedly(Ret urn(&layerForVerticalScrollbar));
238 ASSERT_TRUE(scrollableArea->hasLayerForHorizontalScrollbar());
239 ASSERT_TRUE(scrollableArea->hasLayerForVerticalScrollbar());
240 EXPECT_CALL(theme, shouldRepaintAllPartsOnInvalidation()).WillRepeatedly(Ret urn(false));
241
242 // First, we'll scroll horizontally, and the theme will require repainting
243 // the back button (i.e. the track).
244 EXPECT_CALL(theme, invalidateOnThumbPositionChange(_, _, _)).WillOnce(Return (BackButtonStartPart));
245 scrollableArea->setScrollPosition(DoublePoint(50, 0), ProgrammaticScroll);
246 EXPECT_TRUE(layerForHorizontalScrollbar.hasTrackedPaintInvalidations());
247 EXPECT_FALSE(layerForVerticalScrollbar.hasTrackedPaintInvalidations());
248 EXPECT_TRUE(horizontalScrollbar->trackNeedsRepaint());
249 EXPECT_FALSE(horizontalScrollbar->thumbNeedsRepaint());
250 layerForHorizontalScrollbar.resetTrackedPaintInvalidations();
251 horizontalScrollbar->clearTrackNeedsRepaint();
252
253 // Next, we'll scroll vertically, but invalidate the thumb.
254 EXPECT_CALL(theme, invalidateOnThumbPositionChange(_, _, _)).WillOnce(Return (ThumbPart));
255 scrollableArea->setScrollPosition(DoublePoint(50, 50), ProgrammaticScroll);
256 EXPECT_FALSE(layerForHorizontalScrollbar.hasTrackedPaintInvalidations());
257 EXPECT_TRUE(layerForVerticalScrollbar.hasTrackedPaintInvalidations());
258 EXPECT_FALSE(verticalScrollbar->trackNeedsRepaint());
259 EXPECT_TRUE(verticalScrollbar->thumbNeedsRepaint());
260 layerForVerticalScrollbar.resetTrackedPaintInvalidations();
261 verticalScrollbar->clearThumbNeedsRepaint();
262
263 // Next we'll scroll in both, but the thumb position moving requires no
264 // invalidations. Nonetheless the GraphicsLayer should be invalidated,
265 // because we still need to update the underlying layer (though no
266 // rasterization will be required).
267 EXPECT_CALL(theme, invalidateOnThumbPositionChange(_, _, _)).Times(2).WillRe peatedly(Return(NoPart));
268 scrollableArea->setScrollPosition(DoublePoint(70, 70), ProgrammaticScroll);
269 EXPECT_TRUE(layerForHorizontalScrollbar.hasTrackedPaintInvalidations());
270 EXPECT_TRUE(layerForVerticalScrollbar.hasTrackedPaintInvalidations());
271 EXPECT_FALSE(horizontalScrollbar->trackNeedsRepaint());
272 EXPECT_FALSE(horizontalScrollbar->thumbNeedsRepaint());
273 EXPECT_FALSE(verticalScrollbar->trackNeedsRepaint());
274 EXPECT_FALSE(verticalScrollbar->thumbNeedsRepaint());
275
276 // Forced GC in order to finalize objects depending on the mock object.
277 Heap::collectAllGarbage();
278 }
279
171 } // namespace blink 280 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp ('k') | third_party/WebKit/Source/platform/scroll/Scrollbar.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698