Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frame rate is locked to 60FPS on devices with frame rate optimization #35162

Closed
ajinasokan opened this issue Jun 27, 2019 · 47 comments
Closed

Frame rate is locked to 60FPS on devices with frame rate optimization #35162

ajinasokan opened this issue Jun 27, 2019 · 47 comments
Assignees
Labels
c: performance Relates to speed or footprint issues (see "perf:" labels) c: rendering UI glitches reported at the engine/skia rendering level e: device-specific Only manifests on certain devices engine flutter/engine repository. See also e: labels. perf: speed Performance issues related to (mostly rendering) speed platform-android Android applications specifically

Comments

@ajinasokan
Copy link

All Flutter apps seem to be locked at 60FPS on One Plus 7 Pro that has 90Hz refresh rate. Every other app including Native apps and OpenGL games runs at 90FPS. Because of this Flutter apps feel slow compared to the rest of the operating system even though there are no performance issues or janks.

It seems apps have to somehow notify the OS that it can do higher framerates. And One Plus OxygenOS seems to do this check and switches between 60 and 90 FPS modes. This XDA article explains how this works and how you can force all apps to use 90FPS. After applying the change mentioned in the article Flutter apps run at 90FPS.

[✓] Flutter (Channel stable, v1.5.4-hotfix.2, on Mac OS X 10.14.5 18F132, locale en-IN)
    • Flutter version 1.5.4-hotfix.2 at /Users/ajinasokan/flutter
    • Framework revision 7a4c33425d (8 weeks ago), 2019-04-29 11:05:24 -0700
    • Engine revision 52c7a1e849
    • Dart version 2.3.0 (build 2.3.0-dev.0.5 a1668566e5)


[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at /Users/ajinasokan/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • ANDROID_HOME = /Users/ajinasokan/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
    • All Android licenses accepted.

[✓] iOS toolchain - develop for iOS devices (Xcode 10.2.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.2.1, Build version 10E1001
    • ios-deploy 1.9.4
    • CocoaPods version 1.5.3

[✓] Android Studio (version 3.4)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 34.0.2
    • Dart plugin version 183.5901
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

[✓] VS Code (version 1.32.3)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 2.25.1

[✓] Connected device (1 available)
    • GM1911 • bc329e0f • android-arm64 • Android 9 (API 28)

• No issues found!
@ajinasokan ajinasokan added the c: performance Relates to speed or footprint issues (see "perf:" labels) label Jun 27, 2019
@ajinasokan
Copy link
Author

Here are some slow-motion videos of Flutter app and Native app.

@Zazo032
Copy link
Contributor

Zazo032 commented Jun 27, 2019

Could it be related to OxygenOS locking some apps to 60fps to save battery?

There's a post in XDA that shows how to force 90hz on all apps, could you try a Flutter app after forcing it?
https://www.xda-developers.com/oneplus-7-pro-true-90hz-display-mode/

@tottomotto
Copy link
Contributor

@ajinasokan can you please use the flutter profiling explained here and post the results.

@ajinasokan
Copy link
Author

@Zazo032 Yes. And Yes. I have mentioned this in the second paragraph. It runs at 90FPS after that.

@tottomotto This is not a performance issue. The app is running perfectly fine without janks and frame drops. Problem is that the number of frames is locked to 60 instead of 90. And as I mentioned in the issue, the problem is gone if I force the device to use 90Hz always. So this is something about letting the OS know that Flutter is capable of doing 90FPS.

@tottomotto
Copy link
Contributor

There is a commit merged in master which might be connected to this.
Can you switch to the master channel and try if the issue persists?
@matthew-carroll can you help out here?

@matthew-carroll
Copy link
Contributor

Is this a regression or a new a problem on a new device? If it's the latter, then the referenced commit wouldn't be related.

Maybe @chinmaygarde or @jason-simmons have some thoughts on this.

@ajinasokan
Copy link
Author

@tottomotto I tried the master channel. But it doesn't seem to fix the issue.

@matthew-carroll This is an issue in One Plus 7 Pro AFAIK. I'm not sure about other Android phones with a higher refresh rate like the Razor phone with 120Hz.

@kazenokage
Copy link

Sounds a bit like this: #31086

@ajinasokan
Copy link
Author

@kazenokage I'm not sure about that. That looks more like regression due to the higher sampling rate. Here it is a lock in refresh rate and gets solved by disabling the optimization of One Plus just by changing the config like this:

adb shell settings put global oneplus_screen_refresh_rate 0

So this is more like a configuration issue rather than a regression.

@yekta
Copy link

yekta commented Jul 2, 2019

I'm having the same problem. Native apps are running at 90 fps but our Flutter apps are not.

@jckpn
Copy link

jckpn commented Jul 3, 2019

Having the same problem on my Razer Phone at 120 Hz. Even when scrolling on PageViews, it will appear to be smooth and then stutter near the end of the page-snapping animation. I'd actually argue the app seems more stuttery than on my Pixel 2 locked at 60 Hz.

On a possibly-related note, I'm having very conflicting reports of smoothness from users of my app that DON'T appear to be spec-related. Specifically OnePlus and LG owners are complaining that the whole UI has dropped frames. However, on my Pixel 2 (and what most users are saying) it runs incredibly smooth as I would expect, despite the Pixel 2's relatively low specs compared to most OnePlus devices. When setting my Razer Phone to 60 Hz, I get this exact same issue. Super weird!

P.S. this seems true for every Flutter app I've tested, including the Flutter gallery. 120 fps appears like 60 and 60 fps appears like 30 with LOTS of random dropped frames.

@ping996
Copy link

ping996 commented Jul 4, 2019

How to get the framerate of flutter for desktop app?

@ajinasokan
Copy link
Author

@ping996 You can enable the performance overlay to see if there are any janks. If none then the app is most probably running at the framerate of your display.

@ajinasokan
Copy link
Author

Folks, I have created a thread in One Plus forum. Hopefully, we will get something out of it. If this is some kind of whitelist of package names maintained by One Plus then we are out of luck. And the only solution will be disabling the framerate optimization.

@hacker1024
Copy link
Contributor

hacker1024 commented Aug 25, 2019

This isn't just a OnePlus issue. I've got a Xiaomi Redmi K20 Pro with the display overclocked to 75Hz, and it's also running flutter apps at 60Hz.
It's running an AOSP based ROM.
Can we change the issue title please?

@ajinasokan ajinasokan changed the title Frame rate locked at 60FPS on One Plus 7 Pro with 90Hz refresh rate Frame rate locked at 60FPS on devices with high refresh rate Sep 10, 2019
@ajinasokan
Copy link
Author

@hacker1024 I have changed the title. This issue is so far confirmed in One Plus 7 Pro, Razor phone and Redmi K20 Pro.

@zitn
Copy link

zitn commented Nov 4, 2019

oneplus 7T and 7Tpro also has this issue.

@escamoteur escamoteur added e: device-specific Only manifests on certain devices c: rendering UI glitches reported at the engine/skia rendering level labels Nov 12, 2019
@escamoteur escamoteur added this to the Goals milestone Nov 12, 2019
@rafalbednarczuk
Copy link

rafalbednarczuk commented Nov 29, 2019

@kazenokage I'm not sure about that. That looks more like regression due to the higher sampling rate. Here it is a lock in refresh rate and gets solved by disabling the optimization of One Plus just by changing the config like this:

adb shell settings put global oneplus_screen_refresh_rate 0

So this is more like a configuration issue rather than a regression.

After executing this command with Oneplus 7T Pro, android studio Frame times window still shows 60FPS

This package https://pub.dev/packages/flutter_fps also shows 60FPS

On the other hand if you use this app in order to show FPS counter it shows 90FPS everywhere
So it seems flutter is locked at 60 and it's not OS problem

@MadeBaruna
Copy link

Locked to 60 fps with realme X2 Pro (90hz display). I already enabled 90hz mode for the app.

@liyuqian
Copy link
Contributor

liyuqian commented Dec 9, 2019

Has anyone of you tried Pixel 4 to see if Flutter app runs at 90Hz there? I think in my experiments, Pixel 4 runs 90Hz for Flutter apps, but my OnePlus 7 Pro only runs 60Hz for Flutter apps. If you can confirm that, we can once again make the issue title more accurate. And hopefully it can give us some clue of what's going wrong here.

@rafalbednarczuk
Copy link

Locked to 60 fps with realme X2 Pro (90hz display). I already enabled 90hz mode for the app.

Do you see 90 FPS in flutter tools in android studio?

@MadeBaruna
Copy link

image
It shows 60 fps, but the profiler says it is targetting 11ms (90fps)

@rafalbednarczuk
Copy link

image
It shows 60 fps, but the profiler says it is targetting 11ms (90fps)

using this command on OnePlus 7T Pro:
adb shell settings put global oneplus_screen_refresh_rate 0
it gives the same results so it seems it is 90FPS

@liyuqian
Copy link
Contributor

liyuqian commented Dec 11, 2019

Yes, I've confirmed the results in #35162 (comment) .

In summary, there are two issues:

  1. OnePlus 7 Pro's normal 90 fps mode is only 60 fps for some apps (e.g., Flutter apps). Here's an article about that. To force 90 fps on all apps, use adb shell settings put global oneplus_screen_refresh_rate 0 as suggested by that article and @rafalbednarczuk . (For comparison, Pixel 4 renders Flutter apps at 90 fps out-of-the-box.)

  2. Flutter plugin in the Android Studio / IntelliJ is giving the wrong fps number (60) even if the app is running at 90 fps. Both Frame rate is locked to 60FPS on devices with frame rate optimization #35162 (comment) and Frame rate is locked to 60FPS on devices with frame rate optimization #35162 (comment) have nice screenshots on that.

The first issue is probably out of Flutter's control, but we should fix the second one. @devoncarew @kenzieschmoll : can you please take the ownership of that (https://github.com/flutter/flutter/issues/46819)?

I'm also changing the issue title to reflect the fact that Flutter is rendering at 90 fps, but the plugin is reporting the wrong number.

After reviewing the comments again, I think this issue #35162 is more about different device manufacturers disabling higher frame rate for Flutter apps by default. Hence I created a new issue https://github.com/flutter/flutter/issues/46819 to track the incorrect frame rate shown by Flutter plugin.

@ajinasokan : please keep us posted if you learn something from OnePlus in the bug you filed there. If it's out of Flutter's control, we may have to close the issue here.

@timsneath timsneath added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jan 2, 2020
@ajinasokan
Copy link
Author

@timsneath I have answered this multiple times in this thread. That workaround is effective. I had mentioned it my original issue itself. But it is not something a normal user can do.

Issue now is "frame rate of flutter apps is locked to 60FPS on devices with frame rate optimisation". That workaround is to disable this optimisation.

So far developers has reported this in One Plus 7 Pro, One Plus 7T, One Plus 7T Pro, Razer Phone and Xiaomi Redmi K20 Pro. Install flutter gallery app and scroll any list. Now do the same after enabling that workaround. You can feel the difference. Check the videos I posted in this comment to see the difference in slo-mo.

If a simple spinning cube OpenGL example can run at 90FPS in my phone then flutter is missing something.

@no-response no-response bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jan 3, 2020
@timsneath timsneath changed the title Frame rate locked at 60FPS on devices with high refresh rate Frame rate is locked to 60FPS on devices with frame rate optimization Jan 3, 2020
@timsneath
Copy link
Contributor

Great, thanks! I've updated the issue title accordingly.

@timsneath timsneath added engine flutter/engine repository. See also e: labels. perf: speed Performance issues related to (mostly rendering) speed labels Jan 3, 2020
@kenzieschmoll
Copy link
Member

Tooling issue incorrectly showing 60 FPS for 90 FPS device was resolved in flutter/flutter-intellij#4289. This will be included in the next plugin release. Fix verified with a Pixel 4.

Before:
Screen Shot 2020-01-16 at 9 38 35 AM

After:
Screen Shot 2020-01-16 at 9 33 14 AM

@xihuny
Copy link

xihuny commented Feb 2, 2020

When I execute adb shell settings put global oneplus_screen_refresh_rate 0, it feels like it's showing at 90 fps. But if I select 90Hz refresh rate from settings it looks like framerate is 60 fps.

Forcing the app to show 90 fps using the adb command is not an option here. As far as I know AliExpress app is built with flutter. It's showing 90 fps without the adb command.

@liyuqian
Copy link
Contributor

liyuqian commented Feb 4, 2020

@kangwang1988 : do you know if and how AliExpress is able to run Flutter at 90 fps without adb shell settings put global oneplus_screen_refresh_rate 0 on One Plus 7 Pro?

@ajinasokan
Copy link
Author

@xihuny @liyuqian Alibaba embeds Flutter into their native apps. What you might be looking at could be a native screen and not Flutter.

@xihuny
Copy link

xihuny commented Feb 4, 2020

@xihuny @liyuqian Alibaba embeds Flutter into their native apps. What you might be looking at could be a native screen and not Flutter.

I think so too. Take a look at this @liyuqian https://flutter.dev/docs/development/add-to-app

@sebe
Copy link

sebe commented Feb 4, 2020

Maybe One Plus is white listing apps like google chrome, an xda article, see link below, from June 2019 say -

"If an app uses SurfaceView, TextureView, or NativeActivity, then the OnePlus 7 Pro will run at 60Hz. However, there are special cases like the Google Chrome browser that uses SurfaceView, but can still be viewed in 90Hz."

https://www.xda-developers.com/oneplus-7-pro-true-90hz-display-mode/

@liyuqian
Copy link
Contributor

liyuqian commented Mar 23, 2020

From the information so far, it seems there's nothing that Flutter engineers can do to unlock the 60+fps on certain devices like OnePlus7 Pro. It's controlled by the hardware manufacturer. I'm closing this issue for now. Please feel free to reopen it if someone finds a way for Flutter to unlock it without hardware manufacturer's involvement.

@zoeyfan
Copy link

zoeyfan commented Mar 24, 2020

We will reach out to the manufacture to be what can be done here.

@zoeyfan zoeyfan reopened this Mar 24, 2020
@zoeyfan
Copy link

zoeyfan commented Mar 27, 2020

We have heard back from One plus, here are their official recommendation:

  1. OnePlus 7 Pro currently use a 90Hz high-frame-rate screen. This screen can work in multiple modes:
    -> High frame rate mode can provide a UX smooth experience;
    -> Low frame rate mode can save power.
    In order to balance performance and power consumption, we customized our own frame rate control logic based on Android native logic.
    Generally, the screen will work at a high frame rate, but in certain scenarios, the system will switch the screen to a low frame rate.
    Due to the introduction of this mechanism, there may be a problem that the app wants the screen to run at a high frame rate, but is forced to be set to a low frame rate by the system.

  2. How to set fps rate by app itself?
    If an app needs to set the frame rate. First, getSupportedModes() gets the list of supported modes on this screen, then iterates through the list, finds the modeId according to the desired resolution and refresh rate, and assigns it to the preferredDisplayModeId of the window. So when the app is in the foreground, the screen will work in the desired mode.

Description:
https://developer.android.com/reference/android/view/WindowManager.LayoutParams#preferredDisplayModeId
https://developer.android.com/reference/android/view/Display.Mode

It should be noted that when the app sets the screen refresh rate, the resolution should not be changed, so you need to use getMode to get the current resolution of the phone as a reference.

@liyuqian
Copy link
Contributor

@xster : do you think that we should provide an API in Dart to set the preferredDisplayModeId on Android? Or maybe provide a plugin to help set it?

@liyuqian liyuqian added the platform-android Android applications specifically label Mar 27, 2020
@xster
Copy link
Member

xster commented Mar 27, 2020

Thanks for coordinating @zoeyfan, the summary is helpful.
Given the present API docs on https://developer.android.com/reference/android/view/WindowManager.LayoutParams#preferredDisplayModeId and the vagueness of its contract (I almost get the impression that the primary use case is for setting the resolution on those energy adaptive displays), I wouldn't bake it into the framework until it's clearer. A plugin is reasonable. I expect there to be a lot of OEM specific checks too.

@liyuqian
Copy link
Contributor

@ajinasokan : are you interested in writing such a plugin? Flutter team currently doesn't have a bandwidth to implement it in the short term, but I'm very happy to help reviewing it 😃

@ajinasokan
Copy link
Author

@liyuqian Yeah, sure. I will try. How should I do it? I felt like the right place to put it will be dart:ui's Window class. But that will require a lot of involvement from all of you. So I believe the better approach for now will be to make it as an external plugin?

@liyuqian
Copy link
Contributor

liyuqian commented Apr 1, 2020

@ajinasokan : Yes, an external plugin is a better approach. Plugin flutter_windowmanager is a good example. I think all you need is to expose different modes from Display.getSupportedModes() to Dart, let the user choose a modeId, and then set it through Window.setAttributes.

@ajinasokan
Copy link
Author

Folks, I have made a plugin as @liyuqian suggested. Implementation is quite rough. But gets things done in my OnePlus 7 Pro. Check it out in your device and let me know if it works and if I have missed anything.

This plugin allows you to choose a specific combination of resolution and frame rate, from a set of modes defined by the device.

Here is the repo: ajinasokan/flutter_displaymode
Package: pub.dev/packages/flutter_displaymode

@liyuqian
Copy link
Contributor

liyuqian commented Apr 6, 2020

Thank you @ajinasokan ! Closing this issue.

@lock
Copy link

lock bot commented Apr 25, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@lock lock bot locked and limited conversation to collaborators Apr 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
c: performance Relates to speed or footprint issues (see "perf:" labels) c: rendering UI glitches reported at the engine/skia rendering level e: device-specific Only manifests on certain devices engine flutter/engine repository. See also e: labels. perf: speed Performance issues related to (mostly rendering) speed platform-android Android applications specifically
Projects
None yet
Development

No branches or pull requests