This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
[ios] Lock refresh rate to 80fps when threads are merged #39172
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,8 +12,12 @@ | |
|
|
||
| #include "flutter/common/task_runners.h" | ||
| #include "flutter/fml/logging.h" | ||
| #include "flutter/fml/memory/task_runner_checker.h" | ||
| #include "flutter/fml/trace_event.h" | ||
|
|
||
| // When calculating refresh rate diffrence, anything within 0.1 fps is ignored. | ||
| const static double kRefreshRateDiffToIgnore = 0.1; | ||
|
|
||
| namespace flutter { | ||
|
|
||
| VsyncWaiterIOS::VsyncWaiterIOS(const flutter::TaskRunners& task_runners) | ||
|
|
@@ -26,6 +30,7 @@ | |
| client_ = | ||
| fml::scoped_nsobject{[[VSyncClient alloc] initWithTaskRunner:task_runners_.GetUITaskRunner() | ||
| callback:callback]}; | ||
| max_refresh_rate_ = [DisplayLinkManager displayRefreshRate]; | ||
| } | ||
|
|
||
| VsyncWaiterIOS::~VsyncWaiterIOS() { | ||
|
|
@@ -35,6 +40,19 @@ | |
| } | ||
|
|
||
| void VsyncWaiterIOS::AwaitVSync() { | ||
| double new_max_refresh_rate = [DisplayLinkManager displayRefreshRate]; | ||
| if (fml::TaskRunnerChecker::RunsOnTheSameThread( | ||
| task_runners_.GetRasterTaskRunner()->GetTaskQueueId(), | ||
| task_runners_.GetPlatformTaskRunner()->GetTaskQueueId())) { | ||
| // Pressure tested on iPhone 13 pro, the oldest iPhone that supports refresh rate greater than | ||
| // 60fps. A flutter app can handle fast scrolling on 80 fps with 6 PlatformViews in the scene at | ||
| // the same time. | ||
| new_max_refresh_rate = 80; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I originally set it to 60, but it looks like we can def hit 80 consistently. I decided to lock it at 80 so the scrolling with PlatformView is still smoother than 60fps. This might change when we re-evaluate what the default fps we want the Flutter apps to run on after we implement a new API for the APP to set refresh rates, see flutter/flutter#119268
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a comment for why you chose this? What hardware did you try? |
||
| } | ||
| if (fabs(new_max_refresh_rate - max_refresh_rate_) > kRefreshRateDiffToIgnore) { | ||
| max_refresh_rate_ = new_max_refresh_rate; | ||
| [client_.get() setMaxRefreshRate:max_refresh_rate_]; | ||
| } | ||
| [client_.get() await]; | ||
| } | ||
|
|
||
|
|
@@ -43,6 +61,10 @@ | |
| return [client_.get() getRefreshRate]; | ||
| } | ||
|
|
||
| fml::scoped_nsobject<VSyncClient> VsyncWaiterIOS::GetVsyncClient() const { | ||
| return client_; | ||
| } | ||
|
|
||
| } // namespace flutter | ||
|
|
||
| @implementation VSyncClient { | ||
|
|
@@ -64,7 +86,7 @@ - (instancetype)initWithTaskRunner:(fml::RefPtr<fml::TaskRunner>)task_runner | |
| }; | ||
| display_link_.get().paused = YES; | ||
|
|
||
| [self setMaxRefreshRateIfEnabled]; | ||
| [self setMaxRefreshRate:[DisplayLinkManager displayRefreshRate]]; | ||
|
|
||
| task_runner->PostTask([client = [self retain]]() { | ||
| [client->display_link_.get() addToRunLoop:[NSRunLoop currentRunLoop] | ||
|
|
@@ -76,15 +98,12 @@ - (instancetype)initWithTaskRunner:(fml::RefPtr<fml::TaskRunner>)task_runner | |
| return self; | ||
| } | ||
|
|
||
| - (void)setMaxRefreshRateIfEnabled { | ||
| NSNumber* minimumFrameRateDisabled = | ||
| [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"]; | ||
| if (![minimumFrameRateDisabled boolValue]) { | ||
| - (void)setMaxRefreshRate:(double)refreshRate { | ||
| if (!DisplayLinkManager.maxRefreshRateEnabledOnIPhone) { | ||
| return; | ||
| } | ||
| double maxFrameRate = fmax([DisplayLinkManager displayRefreshRate], 60); | ||
| double maxFrameRate = fmax(refreshRate, 60); | ||
| double minFrameRate = fmax(maxFrameRate / 2, 60); | ||
|
|
||
| if (@available(iOS 15.0, *)) { | ||
| display_link_.get().preferredFrameRateRange = | ||
| CAFrameRateRangeMake(minFrameRate, maxFrameRate, maxFrameRate); | ||
|
|
@@ -170,4 +189,9 @@ - (void)onDisplayLink:(CADisplayLink*)link { | |
| // no-op. | ||
| } | ||
|
|
||
| + (BOOL)maxRefreshRateEnabledOnIPhone { | ||
| return [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"] | ||
| boolValue]; | ||
| } | ||
|
|
||
| @end | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pro-motion iPad Pros too, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only for iPhone, iPad always has high refresh rate on, let me add a comment about it too.