1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "APZCBasicTester.h"
8 #include "APZTestCommon.h"
9
10 #include "InputUtils.h"
11
TEST_F(APZCBasicTester,Overzoom)12 TEST_F(APZCBasicTester, Overzoom) {
13 // the visible area of the document in CSS pixels is x=10 y=0 w=100 h=100
14 FrameMetrics fm;
15 fm.SetCompositionBounds(ParentLayerRect(0, 0, 100, 100));
16 fm.SetScrollableRect(CSSRect(0, 0, 125, 150));
17 fm.SetVisualScrollOffset(CSSPoint(10, 0));
18 fm.SetZoom(CSSToParentLayerScale2D(1.0, 1.0));
19 fm.SetIsRootContent(true);
20 apzc->SetFrameMetrics(fm);
21
22 MakeApzcZoomable();
23
24 EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
25
26 PinchWithPinchInputAndCheckStatus(apzc, ScreenIntPoint(50, 50), 0.5, true);
27
28 fm = apzc->GetFrameMetrics();
29 EXPECT_EQ(0.8f, fm.GetZoom().ToScaleFactor().scale);
30 // bug 936721 - PGO builds introduce rounding error so
31 // use a fuzzy match instead
32 EXPECT_LT(std::abs(fm.GetVisualScrollOffset().x), 1e-5);
33 EXPECT_LT(std::abs(fm.GetVisualScrollOffset().y), 1e-5);
34 }
35
TEST_F(APZCBasicTester,SimpleTransform)36 TEST_F(APZCBasicTester, SimpleTransform) {
37 ParentLayerPoint pointOut;
38 AsyncTransform viewTransformOut;
39 apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
40
41 EXPECT_EQ(ParentLayerPoint(), pointOut);
42 EXPECT_EQ(AsyncTransform(), viewTransformOut);
43 }
44
TEST_F(APZCBasicTester,ComplexTransform)45 TEST_F(APZCBasicTester, ComplexTransform) {
46 // This test assumes there is a page that gets rendered to
47 // two layers. In CSS pixels, the first layer is 50x50 and
48 // the second layer is 25x50. The widget scale factor is 3.0
49 // and the presShell resolution is 2.0. Therefore, these layers
50 // end up being 300x300 and 150x300 in layer pixels.
51 //
52 // The second (child) layer has an additional CSS transform that
53 // stretches it by 2.0 on the x-axis. Therefore, after applying
54 // CSS transforms, the two layers are the same size in screen
55 // pixels.
56 //
57 // The screen itself is 24x24 in screen pixels (therefore 4x4 in
58 // CSS pixels). The displayport is 1 extra CSS pixel on all
59 // sides.
60
61 RefPtr<TestAsyncPanZoomController> childApzc =
62 new TestAsyncPanZoomController(LayersId{0}, mcc, tm);
63
64 const char* layerTreeSyntax = "c(c)";
65 // LayerID 0 1
66 nsIntRegion layerVisibleRegion[] = {
67 nsIntRegion(IntRect(0, 0, 300, 300)),
68 nsIntRegion(IntRect(0, 0, 150, 300)),
69 };
70 Matrix4x4 transforms[] = {
71 Matrix4x4(),
72 Matrix4x4(),
73 };
74 transforms[0].PostScale(
75 0.5f, 0.5f,
76 1.0f); // this results from the 2.0 resolution on the root layer
77 transforms[1].PostScale(
78 2.0f, 1.0f,
79 1.0f); // this is the 2.0 x-axis CSS transform on the child layer
80
81 nsTArray<RefPtr<Layer> > layers;
82 RefPtr<LayerManager> lm;
83 RefPtr<Layer> root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion,
84 transforms, lm, layers);
85
86 ScrollMetadata metadata;
87 FrameMetrics& metrics = metadata.GetMetrics();
88 metrics.SetCompositionBounds(ParentLayerRect(0, 0, 24, 24));
89 metrics.SetDisplayPort(CSSRect(-1, -1, 6, 6));
90 metrics.SetVisualScrollOffset(CSSPoint(10, 10));
91 metrics.SetLayoutViewport(CSSRect(10, 10, 8, 8));
92 metrics.SetScrollableRect(CSSRect(0, 0, 50, 50));
93 metrics.SetCumulativeResolution(LayoutDeviceToLayerScale2D(2, 2));
94 metrics.SetPresShellResolution(2.0f);
95 metrics.SetZoom(CSSToParentLayerScale2D(6, 6));
96 metrics.SetDevPixelsPerCSSPixel(CSSToLayoutDeviceScale(3));
97 metrics.SetScrollId(ScrollableLayerGuid::START_SCROLL_ID);
98
99 ScrollMetadata childMetadata = metadata;
100 FrameMetrics& childMetrics = childMetadata.GetMetrics();
101 childMetrics.SetScrollId(ScrollableLayerGuid::START_SCROLL_ID + 1);
102
103 layers[0]->SetScrollMetadata(metadata);
104 layers[1]->SetScrollMetadata(childMetadata);
105
106 ParentLayerPoint pointOut;
107 AsyncTransform viewTransformOut;
108
109 // Both the parent and child layer should behave exactly the same here,
110 // because the CSS transform on the child layer does not affect the
111 // SampleContentTransformForFrame code
112
113 // initial transform
114 apzc->SetFrameMetrics(metrics);
115 apzc->NotifyLayersUpdated(metadata, true, true);
116 apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
117 EXPECT_EQ(AsyncTransform(LayerToParentLayerScale(1), ParentLayerPoint()),
118 viewTransformOut);
119 EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
120
121 childApzc->SetFrameMetrics(childMetrics);
122 childApzc->NotifyLayersUpdated(childMetadata, true, true);
123 childApzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
124 EXPECT_EQ(AsyncTransform(LayerToParentLayerScale(1), ParentLayerPoint()),
125 viewTransformOut);
126 EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
127
128 // do an async scroll by 5 pixels and check the transform
129 metrics.ScrollBy(CSSPoint(5, 0));
130 apzc->SetFrameMetrics(metrics);
131 apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
132 EXPECT_EQ(
133 AsyncTransform(LayerToParentLayerScale(1), ParentLayerPoint(-30, 0)),
134 viewTransformOut);
135 EXPECT_EQ(ParentLayerPoint(90, 60), pointOut);
136
137 childMetrics.ScrollBy(CSSPoint(5, 0));
138 childApzc->SetFrameMetrics(childMetrics);
139 childApzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
140 EXPECT_EQ(
141 AsyncTransform(LayerToParentLayerScale(1), ParentLayerPoint(-30, 0)),
142 viewTransformOut);
143 EXPECT_EQ(ParentLayerPoint(90, 60), pointOut);
144
145 // do an async zoom of 1.5x and check the transform
146 metrics.ZoomBy(1.5f);
147 apzc->SetFrameMetrics(metrics);
148 apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
149 EXPECT_EQ(
150 AsyncTransform(LayerToParentLayerScale(1.5), ParentLayerPoint(-45, 0)),
151 viewTransformOut);
152 EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
153
154 childMetrics.ZoomBy(1.5f);
155 childApzc->SetFrameMetrics(childMetrics);
156 childApzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
157 EXPECT_EQ(
158 AsyncTransform(LayerToParentLayerScale(1.5), ParentLayerPoint(-45, 0)),
159 viewTransformOut);
160 EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
161
162 childApzc->Destroy();
163 }
164
TEST_F(APZCBasicTester,Fling)165 TEST_F(APZCBasicTester, Fling) {
166 SCOPED_GFX_PREF_FLOAT("apz.fling_min_velocity_threshold", 0.0f);
167 int touchStart = 50;
168 int touchEnd = 10;
169 ParentLayerPoint pointOut;
170 AsyncTransform viewTransformOut;
171
172 // Fling down. Each step scroll further down
173 Pan(apzc, touchStart, touchEnd);
174 ParentLayerPoint lastPoint;
175 for (int i = 1; i < 50; i += 1) {
176 apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut,
177 TimeDuration::FromMilliseconds(1));
178 EXPECT_GT(pointOut.y, lastPoint.y);
179 lastPoint = pointOut;
180 }
181 }
182
183 #ifndef MOZ_WIDGET_ANDROID // Maybe fails on Android
TEST_F(APZCBasicTester,ResumeInterruptedTouchDrag_Bug1592435)184 TEST_F(APZCBasicTester, ResumeInterruptedTouchDrag_Bug1592435) {
185 // Start a touch-drag and scroll some amount, not lifting the finger.
186 SCOPED_GFX_PREF_FLOAT("apz.touch_start_tolerance", 1.0f / 1000.0f);
187 ScreenIntPoint touchPos(10, 50);
188 uint64_t touchBlock = TouchDown(apzc, touchPos, mcc->Time()).mInputBlockId;
189 SetDefaultAllowedTouchBehavior(apzc, touchBlock);
190 for (int i = 0; i < 20; ++i) {
191 touchPos.y -= 1;
192 mcc->AdvanceByMillis(1);
193 TouchMove(apzc, touchPos, mcc->Time());
194 }
195
196 // Take note of the scroll offset before the interruption.
197 CSSPoint scrollOffsetBeforeInterruption =
198 apzc->GetFrameMetrics().GetVisualScrollOffset();
199
200 // Have the main thread interrupt the touch-drag by sending
201 // a main thread scroll update to a nearby location.
202 CSSPoint mainThreadOffset = scrollOffsetBeforeInterruption;
203 mainThreadOffset.y -= 5;
204 ScrollMetadata metadata = apzc->GetScrollMetadata();
205 metadata.GetMetrics().SetLayoutScrollOffset(mainThreadOffset);
206 nsTArray<ScrollPositionUpdate> scrollUpdates;
207 scrollUpdates.AppendElement(ScrollPositionUpdate::NewScroll(
208 ScrollOrigin::Other, CSSPoint::ToAppUnits(mainThreadOffset)));
209 metadata.SetScrollUpdates(scrollUpdates);
210 metadata.GetMetrics().SetScrollGeneration(
211 scrollUpdates.LastElement().GetGeneration());
212 apzc->NotifyLayersUpdated(metadata, false, true);
213
214 // Continue and finish the touch-drag gesture.
215 for (int i = 0; i < 20; ++i) {
216 touchPos.y -= 1;
217 mcc->AdvanceByMillis(1);
218 TouchMove(apzc, touchPos, mcc->Time());
219 }
220
221 // Check that the portion of the touch-drag that occurred after
222 // the interruption caused additional scrolling.
223 CSSPoint finalScrollOffset = apzc->GetFrameMetrics().GetVisualScrollOffset();
224 EXPECT_GT(finalScrollOffset.y, scrollOffsetBeforeInterruption.y);
225
226 // Now do the same thing, but for a visual scroll update.
227 scrollOffsetBeforeInterruption =
228 apzc->GetFrameMetrics().GetVisualScrollOffset();
229 mainThreadOffset = scrollOffsetBeforeInterruption;
230 mainThreadOffset.y -= 5;
231 metadata = apzc->GetScrollMetadata();
232 metadata.GetMetrics().SetVisualDestination(mainThreadOffset);
233 metadata.GetMetrics().SetScrollGeneration(ScrollGeneration::New());
234 metadata.GetMetrics().SetVisualScrollUpdateType(FrameMetrics::eMainThread);
235 scrollUpdates.Clear();
236 metadata.SetScrollUpdates(scrollUpdates);
237 apzc->NotifyLayersUpdated(metadata, false, true);
238 for (int i = 0; i < 20; ++i) {
239 touchPos.y -= 1;
240 mcc->AdvanceByMillis(1);
241 TouchMove(apzc, touchPos, mcc->Time());
242 }
243 finalScrollOffset = apzc->GetFrameMetrics().GetVisualScrollOffset();
244 EXPECT_GT(finalScrollOffset.y, scrollOffsetBeforeInterruption.y);
245
246 // Clean up by ending the touch gesture.
247 mcc->AdvanceByMillis(1);
248 TouchUp(apzc, touchPos, mcc->Time());
249 }
250 #endif
251
TEST_F(APZCBasicTester,RelativeScrollOffset)252 TEST_F(APZCBasicTester, RelativeScrollOffset) {
253 // Set up initial conditions: zoomed in, layout offset at (100, 100),
254 // visual offset at (120, 120); the relative offset is therefore (20, 20).
255 ScrollMetadata metadata;
256 FrameMetrics& metrics = metadata.GetMetrics();
257 metrics.SetScrollableRect(CSSRect(0, 0, 1000, 1000));
258 metrics.SetLayoutViewport(CSSRect(100, 100, 100, 100));
259 metrics.SetZoom(CSSToParentLayerScale2D(2.0, 2.0));
260 metrics.SetCompositionBounds(ParentLayerRect(0, 0, 100, 100));
261 metrics.SetVisualScrollOffset(CSSPoint(120, 120));
262 metrics.SetIsRootContent(true);
263 apzc->SetFrameMetrics(metrics);
264
265 // Scroll the layout viewport to (200, 200).
266 ScrollMetadata mainThreadMetadata = metadata;
267 FrameMetrics& mainThreadMetrics = mainThreadMetadata.GetMetrics();
268 mainThreadMetrics.SetLayoutScrollOffset(CSSPoint(200, 200));
269 nsTArray<ScrollPositionUpdate> scrollUpdates;
270 scrollUpdates.AppendElement(ScrollPositionUpdate::NewScroll(
271 ScrollOrigin::Other, CSSPoint::ToAppUnits(CSSPoint(200, 200))));
272 mainThreadMetadata.SetScrollUpdates(scrollUpdates);
273 mainThreadMetrics.SetScrollGeneration(
274 scrollUpdates.LastElement().GetGeneration());
275 apzc->NotifyLayersUpdated(mainThreadMetadata, /*isFirstPaint=*/false,
276 /*thisLayerTreeUpdated=*/true);
277
278 // Check that the relative offset has been preserved.
279 metrics = apzc->GetFrameMetrics();
280 EXPECT_EQ(metrics.GetLayoutScrollOffset(), CSSPoint(200, 200));
281 EXPECT_EQ(metrics.GetVisualScrollOffset(), CSSPoint(220, 220));
282 }
283
TEST_F(APZCBasicTester,MultipleSmoothScrollsSmooth)284 TEST_F(APZCBasicTester, MultipleSmoothScrollsSmooth) {
285 // We want to test that if we send multiple smooth scroll requests that we
286 // still smoothly animate, ie that we get non-zero change every frame while
287 // the animation is running.
288
289 ScrollMetadata metadata;
290 FrameMetrics& metrics = metadata.GetMetrics();
291 metrics.SetScrollableRect(CSSRect(0, 0, 100, 10000));
292 metrics.SetLayoutViewport(CSSRect(0, 0, 100, 100));
293 metrics.SetZoom(CSSToParentLayerScale2D(1.0, 1.0));
294 metrics.SetCompositionBounds(ParentLayerRect(0, 0, 100, 100));
295 metrics.SetVisualScrollOffset(CSSPoint(0, 0));
296 metrics.SetIsRootContent(true);
297 apzc->SetFrameMetrics(metrics);
298
299 // Structure of this test.
300 // -send a pure relative smooth scroll request via NotifyLayersUpdated
301 // -advance animations a few times, check that scroll offset is increasing
302 // after the first few advances
303 // -send a pure relative smooth scroll request via NotifyLayersUpdated
304 // -advance animations a few times, check that scroll offset is increasing
305 // -send a pure relative smooth scroll request via NotifyLayersUpdated
306 // -advance animations a few times, check that scroll offset is increasing
307
308 ScrollMetadata metadata2 = metadata;
309 nsTArray<ScrollPositionUpdate> scrollUpdates2;
310 scrollUpdates2.AppendElement(ScrollPositionUpdate::NewPureRelativeScroll(
311 ScrollOrigin::Other, ScrollMode::Smooth,
312 CSSPoint::ToAppUnits(CSSPoint(0, 200))));
313 metadata2.SetScrollUpdates(scrollUpdates2);
314 metadata2.GetMetrics().SetScrollGeneration(
315 scrollUpdates2.LastElement().GetGeneration());
316 apzc->NotifyLayersUpdated(metadata2, /*isFirstPaint=*/false,
317 /*thisLayerTreeUpdated=*/true);
318
319 // Get the animation going
320 for (uint32_t i = 0; i < 3; i++) {
321 SampleAnimationOneFrame();
322 }
323
324 float offset =
325 apzc->GetCurrentAsyncScrollOffset(AsyncPanZoomController::eForCompositing)
326 .y;
327 ASSERT_GT(offset, 0);
328 float lastOffset = offset;
329
330 for (uint32_t i = 0; i < 2; i++) {
331 for (uint32_t j = 0; j < 3; j++) {
332 SampleAnimationOneFrame();
333 offset = apzc->GetCurrentAsyncScrollOffset(
334 AsyncPanZoomController::eForCompositing)
335 .y;
336 ASSERT_GT(offset, lastOffset);
337 lastOffset = offset;
338 }
339
340 ScrollMetadata metadata3 = metadata;
341 nsTArray<ScrollPositionUpdate> scrollUpdates3;
342 scrollUpdates3.AppendElement(ScrollPositionUpdate::NewPureRelativeScroll(
343 ScrollOrigin::Other, ScrollMode::Smooth,
344 CSSPoint::ToAppUnits(CSSPoint(0, 200))));
345 metadata3.SetScrollUpdates(scrollUpdates3);
346 metadata3.GetMetrics().SetScrollGeneration(
347 scrollUpdates3.LastElement().GetGeneration());
348 apzc->NotifyLayersUpdated(metadata3, /*isFirstPaint=*/false,
349 /*thisLayerTreeUpdated=*/true);
350 }
351
352 for (uint32_t j = 0; j < 7; j++) {
353 SampleAnimationOneFrame();
354 offset = apzc->GetCurrentAsyncScrollOffset(
355 AsyncPanZoomController::eForCompositing)
356 .y;
357 ASSERT_GT(offset, lastOffset);
358 lastOffset = offset;
359 }
360 }
361
TEST_F(APZCBasicTester,ZoomAndScrollableRectChangeAfterZoomChange)362 TEST_F(APZCBasicTester, ZoomAndScrollableRectChangeAfterZoomChange) {
363 // We want to check that a small scrollable rect change (which causes us to
364 // reclamp our scroll position, including in the sampled state) does not move
365 // the scroll offset in the sample state based the zoom in the apzc, only
366 // based on the zoom in the sampled state.
367
368 // First we zoom in to the right hand side. Then start zooming out, then send
369 // a scrollable rect change and check that it doesn't change the sampled state
370 // scroll offset.
371
372 ScrollMetadata metadata;
373 FrameMetrics& metrics = metadata.GetMetrics();
374 metrics.SetCompositionBounds(ParentLayerRect(0, 0, 100, 100));
375 metrics.SetScrollableRect(CSSRect(0, 0, 100, 1000));
376 metrics.SetLayoutViewport(CSSRect(0, 0, 100, 100));
377 metrics.SetVisualScrollOffset(CSSPoint(0, 0));
378 metrics.SetZoom(CSSToParentLayerScale2D(1.0, 1.0));
379 metrics.SetIsRootContent(true);
380 apzc->SetFrameMetrics(metrics);
381
382 MakeApzcZoomable();
383
384 // Zoom to right side.
385 ZoomTarget zoomTarget{CSSRect(75, 25, 25, 25), Nothing()};
386 apzc->ZoomToRect(zoomTarget, 0);
387
388 // Run the animation to completion, should take 250ms/16.67ms = 15 frames, but
389 // do extra to make sure.
390 for (uint32_t i = 0; i < 30; i++) {
391 SampleAnimationOneFrame();
392 }
393
394 EXPECT_FALSE(apzc->IsAsyncZooming());
395
396 // Zoom out.
397 ZoomTarget zoomTarget2{CSSRect(0, 0, 100, 100), Nothing()};
398 apzc->ZoomToRect(zoomTarget2, 0);
399
400 // Run the animation a few times to get it going.
401 for (uint32_t i = 0; i < 2; i++) {
402 SampleAnimationOneFrame();
403 }
404
405 // Check that it is decreasing in scale.
406 float prevScale =
407 apzc->GetCurrentPinchZoomScale(AsyncPanZoomController::eForCompositing)
408 .scale;
409 for (uint32_t i = 0; i < 2; i++) {
410 SampleAnimationOneFrame();
411 float scale =
412 apzc->GetCurrentPinchZoomScale(AsyncPanZoomController::eForCompositing)
413 .scale;
414 ASSERT_GT(prevScale, scale);
415 prevScale = scale;
416 }
417
418 float offset =
419 apzc->GetCurrentAsyncScrollOffset(AsyncPanZoomController::eForCompositing)
420 .x;
421
422 // Change the scrollable rect slightly to trigger a reclamp.
423 ScrollMetadata metadata2 = metadata;
424 metadata2.GetMetrics().SetScrollableRect(CSSRect(0, 0, 100, 1000.2));
425 apzc->NotifyLayersUpdated(metadata2, /*isFirstPaint=*/false,
426 /*thisLayerTreeUpdated=*/true);
427
428 float newOffset =
429 apzc->GetCurrentAsyncScrollOffset(AsyncPanZoomController::eForCompositing)
430 .x;
431
432 ASSERT_EQ(newOffset, offset);
433 }
434
TEST_F(APZCBasicTester,ZoomToRectAndCompositionBoundsChange)435 TEST_F(APZCBasicTester, ZoomToRectAndCompositionBoundsChange) {
436 // We want to check that content sending a composition bounds change (due to
437 // addition of scrollbars) during a zoom animation does not cause us to take
438 // the out of date content resolution.
439
440 ScrollMetadata metadata;
441 FrameMetrics& metrics = metadata.GetMetrics();
442 metrics.SetCompositionBounds(ParentLayerRect(0, 0, 100, 100));
443 metrics.SetCompositionBoundsWidthIgnoringScrollbars(ParentLayerCoord{100});
444 metrics.SetScrollableRect(CSSRect(0, 0, 100, 1000));
445 metrics.SetLayoutViewport(CSSRect(0, 0, 100, 100));
446 metrics.SetVisualScrollOffset(CSSPoint(0, 0));
447 metrics.SetZoom(CSSToParentLayerScale2D(1.0, 1.0));
448 metrics.SetIsRootContent(true);
449 apzc->SetFrameMetrics(metrics);
450
451 MakeApzcZoomable();
452
453 // Start a zoom to a rect.
454 ZoomTarget zoomTarget{CSSRect(25, 25, 25, 25), Nothing()};
455 apzc->ZoomToRect(zoomTarget, 0);
456
457 // Run the animation a few times to get it going.
458 // Check that it is increasing in scale.
459 float prevScale =
460 apzc->GetCurrentPinchZoomScale(AsyncPanZoomController::eForCompositing)
461 .scale;
462 for (uint32_t i = 0; i < 3; i++) {
463 SampleAnimationOneFrame();
464 float scale =
465 apzc->GetCurrentPinchZoomScale(AsyncPanZoomController::eForCompositing)
466 .scale;
467 ASSERT_GE(scale, prevScale);
468 prevScale = scale;
469 }
470
471 EXPECT_TRUE(apzc->IsAsyncZooming());
472
473 // Simulate the appearance of a scrollbar by reducing the width of
474 // the composition bounds, while keeping
475 // mCompositionBoundsWidthIgnoringScrollbars unchanged.
476 ScrollMetadata metadata2 = metadata;
477 metadata2.GetMetrics().SetCompositionBounds(ParentLayerRect(0, 0, 90, 100));
478 apzc->NotifyLayersUpdated(metadata2, /*isFirstPaint=*/false,
479 /*thisLayerTreeUpdated=*/true);
480
481 float scale =
482 apzc->GetCurrentPinchZoomScale(AsyncPanZoomController::eForCompositing)
483 .scale;
484
485 ASSERT_EQ(scale, prevScale);
486
487 // Run the rest of the animation to completion, should take 250ms/16.67ms = 15
488 // frames total, but do extra to make sure.
489 for (uint32_t i = 0; i < 30; i++) {
490 SampleAnimationOneFrame();
491 scale =
492 apzc->GetCurrentPinchZoomScale(AsyncPanZoomController::eForCompositing)
493 .scale;
494 ASSERT_GE(scale, prevScale);
495 prevScale = scale;
496 }
497
498 EXPECT_FALSE(apzc->IsAsyncZooming());
499 }
500