5 #import <OCMock/OCMock.h>
6 #import <XCTest/XCTest.h>
8 #include "flutter/fml/raster_thread_merger.h"
9 #include "flutter/fml/thread.h"
17 auto thread = std::make_unique<fml::Thread>(name);
18 auto runner = thread->GetTaskRunner();
26 - (void)onDisplayLink:(CADisplayLink*)link;
35 - (void)testSetAllowPauseAfterVsyncCorrect {
38 initWithTaskRunner:thread_task_runner
39 callback:[](std::unique_ptr<flutter::FrameTimingsRecorder> recorder) {}];
40 CADisplayLink* link = [vsyncClient getDisplayLink];
43 [vsyncClient onDisplayLink:link];
44 XCTAssertFalse(link.isPaused);
48 [vsyncClient onDisplayLink:link];
49 XCTAssertTrue(link.isPaused);
52 - (void)testSetCorrectVariableRefreshRates {
54 auto callback = [](std::unique_ptr<flutter::FrameTimingsRecorder> recorder) {};
55 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
56 OCMStub([bundleMock objectForInfoDictionaryKey:
@"CADisableMinimumFrameDurationOnPhone"])
59 double maxFrameRate = 120;
60 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
64 CADisplayLink* link = [vsyncClient getDisplayLink];
65 if (@available(iOS 15.0, *)) {
66 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.maximum, maxFrameRate, 0.1);
67 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.preferred, maxFrameRate, 0.1);
68 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.minimum, maxFrameRate / 2, 0.1);
70 XCTAssertEqualWithAccuracy(link.preferredFramesPerSecond, maxFrameRate, 0.1);
74 - (void)testDoNotSetVariableRefreshRatesIfCADisableMinimumFrameDurationOnPhoneIsNotOn {
76 auto callback = [](std::unique_ptr<flutter::FrameTimingsRecorder> recorder) {};
77 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
78 OCMStub([bundleMock objectForInfoDictionaryKey:
@"CADisableMinimumFrameDurationOnPhone"])
81 double maxFrameRate = 120;
82 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
86 CADisplayLink* link = [vsyncClient getDisplayLink];
87 if (@available(iOS 15.0, *)) {
88 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.maximum, 0, 0.1);
89 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.preferred, 0, 0.1);
90 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.minimum, 0, 0.1);
92 XCTAssertEqualWithAccuracy(link.preferredFramesPerSecond, 0, 0.1);
96 - (void)testDoNotSetVariableRefreshRatesIfCADisableMinimumFrameDurationOnPhoneIsNotSet {
98 auto callback = [](std::unique_ptr<flutter::FrameTimingsRecorder> recorder) {};
100 double maxFrameRate = 120;
101 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
104 CADisplayLink* link = [vsyncClient getDisplayLink];
105 if (@available(iOS 15.0, *)) {
106 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.maximum, 0, 0.1);
107 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.preferred, 0, 0.1);
108 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.minimum, 0, 0.1);
110 XCTAssertEqualWithAccuracy(link.preferredFramesPerSecond, 0, 0.1);
114 - (void)testAwaitAndPauseWillWorkCorrectly {
117 initWithTaskRunner:thread_task_runner
118 callback:[](std::unique_ptr<flutter::FrameTimingsRecorder> recorder) {}];
120 CADisplayLink* link = [vsyncClient getDisplayLink];
121 XCTAssertTrue(link.isPaused);
124 XCTAssertFalse(link.isPaused);
127 XCTAssertTrue(link.isPaused);
130 - (void)testRefreshRateUpdatedTo80WhenThraedsMerge {
136 flutter::TaskRunners(
"test", platform_thread_task_runner, raster_thread_task_runner,
137 ui_thread_task_runner, io_thread_task_runner);
140 double maxFrameRate = 120;
141 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
142 [[[mockDisplayLinkManager stub] andReturnValue:@(YES)] maxRefreshRateEnabledOnIPhone];
145 fml::scoped_nsobject<VSyncClient> vsyncClient = vsync_waiter.GetVsyncClient();
146 CADisplayLink* link = [vsyncClient.get() getDisplayLink];
148 if (@available(iOS 15.0, *)) {
149 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.maximum, maxFrameRate, 0.1);
150 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.preferred, maxFrameRate, 0.1);
151 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.minimum, maxFrameRate / 2, 0.1);
153 XCTAssertEqualWithAccuracy(link.preferredFramesPerSecond, maxFrameRate, 0.1);
156 const auto merger = fml::RasterThreadMerger::CreateOrShareThreadMerger(
157 nullptr, platform_thread_task_runner->GetTaskQueueId(),
158 raster_thread_task_runner->GetTaskQueueId());
160 merger->MergeWithLease(5);
161 vsync_waiter.AwaitVSync();
163 if (@available(iOS 15.0, *)) {
164 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.maximum, 80, 0.1);
165 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.preferred, 80, 0.1);
166 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.minimum, 60, 0.1);
168 XCTAssertEqualWithAccuracy(link.preferredFramesPerSecond, 80, 0.1);
171 merger->UnMergeNowIfLastOne();
172 vsync_waiter.AwaitVSync();
174 if (@available(iOS 15.0, *)) {
175 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.maximum, maxFrameRate, 0.1);
176 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.preferred, maxFrameRate, 0.1);
177 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.minimum, maxFrameRate / 2, 0.1);
179 XCTAssertEqualWithAccuracy(link.preferredFramesPerSecond, maxFrameRate, 0.1);
182 if (@available(iOS 14.0, *)) {
184 id processInfo = [NSProcessInfo processInfo];
185 id processInfoPartialMock = OCMPartialMock(processInfo);
186 bool iOSAppOnMac =
true;
187 [OCMStub([processInfoPartialMock isiOSAppOnMac]) andReturnValue:OCMOCK_VALUE(iOSAppOnMac)];
189 merger->MergeWithLease(5);
190 vsync_waiter.AwaitVSync();
193 if (@available(iOS 15.0, *)) {
194 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.maximum, maxFrameRate, 0.1);
195 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.preferred, maxFrameRate, 0.1);
196 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.minimum, maxFrameRate / 2, 0.1);
198 XCTAssertEqualWithAccuracy(link.preferredFramesPerSecond, 80, 0.1);
201 merger->UnMergeNowIfLastOne();
202 vsync_waiter.AwaitVSync();
204 if (@available(iOS 15.0, *)) {
205 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.maximum, maxFrameRate, 0.1);
206 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.preferred, maxFrameRate, 0.1);
207 XCTAssertEqualWithAccuracy(link.preferredFrameRateRange.minimum, maxFrameRate / 2, 0.1);
209 XCTAssertEqualWithAccuracy(link.preferredFramesPerSecond, maxFrameRate, 0.1);