为此,应用可能需要知道当前设备的刷新率。可以通过以下方法来实现:
应用可以通过在其 Window 或 Surface 上设置帧率来影响设备刷新率。这是 Android 11 中引入的一个新功能,允许平台了解应用的渲染需求。应用可以调用以下方法之一:
关于如何使用这些 API,请参考 帧率指南 文档。
系统会根据 Window 或 Surface 上设置的帧率选择最合适的刷新率。
二、刷新率注册
三、刷新率区间设置和匹配
adb shell settings put system min_refresh_rate 60.0 //设置刷新率下限值
adb shell settings put system peak_refresh_rate 120.0 //设置刷新率上限值
通过adb命令修改peak_refresh_rate或者min_refresh_rate时,DisplayModeDirector.java里面的监听哨会捕捉到值的变化,调用onChange方法
OnChange()
-->updateRefreshRateSettingLocked()
-->updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRrefreshRate)
如上updateRefreshRateSettingLocked中,重点调用了updateVoteLocked方法,用于更新每一个优先级对应的参数(主要是该优先级下记录的刷新率变动范围).
mDesiredDisplayModeSpecsListener和onDesiredDisplayModesSpecsChanged()方法的定义和对应初始化流程如下:
新建DesiredDisplayModeSpecsObserver对象,并通过setDesiredDisplayModeSpecsListener赋值给mDesiredDisplayModeSpecsListener:
09-13 02:23:18.779 1034 1086 I DisplayModeDirector: updateVoteLocked(displayId=-1, priority=PRIORITY_USER_SETTING_PEAK_REFRESH_RATE, vote=Vote{width=-1, height=-1, minRefreshRate=0.0, maxRefreshRate=120.0})
09-13 02:23:18.779 1034 1086 I DisplayModeDirector: updateVoteLocked(displayId=-1, priority=PRIORITY_USER_SETTING_MIN_REFRESH_RATE, vote=Vote{width=-1, height=-1, minRefreshRate=50.0, maxRefreshRate=Infinity})
09-13 02:23:18.779 1034 1086 I DisplayModeDirector: updateVoteLocked(displayId=-1, priority=PRIORITY_DEFAULT_REFRESH_RATE, vote=null)
09-13 02:23:18.779 1034 1086 I DisplayModeDirector: updateVoteLocked(displayId=-1, priority=PRIORITY_USER_SETTING_PEAK_REFRESH_RATE, vote=Vote{width=-1, height=-1, minRefreshRate=0.0, maxRefreshRate=120.0})
09-13 02:23:18.779 1034 1086 I DisplayModeDirector: updateVoteLocked(displayId=-1, priority=PRIORITY_USER_SETTING_MIN_REFRESH_RATE, vote=Vote{width=-1, height=-1, minRefreshRate=50.0, maxRefreshRate=Infinity})
09-13 02:23:18.779 1034 1086 I DisplayModeDirector: updateVoteLocked(displayId=-1, priority=PRIORITY_DEFAULT_REFRESH_RATE, vote=null)
09-13 02:23:18.779 1034 1086 I DisplayModeDirector: displayId:0
09-13 02:23:18.779 1034 1086 I DisplayModeDirector: sumarizeVotes:0
09-13 02:23:18.779 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:6
09-13 02:23:18.779 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:5
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes find priority:5, vote:Vote{width=-1, height=-1, minRefreshRate=0.0, maxRefreshRate=120.0}
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes before summary: min:0.0 max:Infinity height:-1 width: -1
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes after-0 summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes after-1 summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:4
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:3
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:2
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes find priority:2, vote:Vote{width=-1, height=-1, minRefreshRate=50.0, maxRefreshRate=Infinity}
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes before summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes after-0 summary: min:50.0 max:120.0 height:-1 width: -1
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes after-1 summary: min:50.0 max:120.0 height:-1 width: -1
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:1
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:0
09-13 02:23:18.780 1034 1086 W DisplayModeDirector: filterModes:{id=1, width=1080, height=2408, fps=50.0}
09-13 02:23:18.780 1034 1086 W DisplayModeDirector: filterModes:{id=2, width=1080, height=2408, fps=60.0}
09-13 02:23:18.780 1034 1086 W DisplayModeDirector: filterModes:{id=3, width=1080, height=2408, fps=90.0}
09-13 02:23:18.780 1034 1086 W DisplayModeDirector: filterModes:{id=4, width=1080, height=2408, fps=120.00001}
09-13 02:23:18.780 1034 1086 W DisplayModeDirector: Found available modes=[1, 2, 3, 4] with lowest priority considered PRIORITY_DEFAULT_REFRESH_RATE and constraints: width=1080, height=2408, minRefreshRate=50.0, maxRefreshRate=120.0
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes:3
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:6
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:5
09-13 02:23:18.780 1034 1086 I DisplayModeDirector: sumarizeVotes find priority:5, vote:Vote{width=-1, height=-1, minRefreshRate=0.0, maxRefreshRate=120.0}
09-13 02:23:18.781 1034 1086 I DisplayModeDirector: sumarizeVotes before summary: min:0.0 max:Infinity height:-1 width: -1
09-13 02:23:18.781 1034 1086 I DisplayModeDirector: sumarizeVotes after-0 summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:23:18.781 1034 1086 I DisplayModeDirector: sumarizeVotes after-1 summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:23:18.781 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:4
09-13 02:23:18.781 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:3
09-13 02:23:18.781 1034 1086 I DisplayModeDirector: App request range: [0 120]
09-13 02:23:18.785 590 737 V RefreshRateConfigs: getRefreshRateForContent 0 layers
09-13 02:23:18.887 590 590 D ha ha : #00 pc 00000000000ffdcc /system/lib64/libsurfaceflinger.so (android::scheduler::RefreshRateConfigs::constructAvailableRefreshRates()+176)
09-13 02:23:18.887 590 590 D ha ha : #01 pc 000000000010004c /system/lib64/libsurfaceflinger.so (android::scheduler::RefreshRateConfigs::setDisplayManagerPolicy(android::scheduler::RefreshRateConfigs::Policy const&)+464)
09-13 02:23:18.887 590 590 D ha ha : #02 pc 00000000001278d4 /system/lib64/libsurfaceflinger.so (android::SurfaceFlinger::setDesiredDisplayConfigSpecsInternal(android::sp<android::DisplayDevice> const&, std::__1::optional<android::scheduler::RefreshRateConfigs::Policy> const&, bool)+432)
09-13 02:23:18.887 590 590 D ha ha : #03 pc 00000000001383f0 /system/lib64/libsurfaceflinger.so (_ZNSt3__120__packaged_task_funcIZN7android14SurfaceFlinger28setDesiredDisplayConfigSpecsERKNS1_2spINS1_7IBinderEEEiffffE4$_63NS_9allocatorIS8_EEFivEEclEv$ed74649543c784cf7bf71a82a57ab79d+300)
09-13 02:23:18.888 590 590 D ha ha : #08 pc 000000000010db58 /system/lib64/libsurfaceflinger.so (android::SurfaceFlinger::run()+20)
09-13 02:23:18.889 590 590 V RefreshRateConfigs: constructAvailableRefreshRates: default 0 group -1 primaryRange=[50.00 120.00] appRequestRange=[0.00 120.00]
09-13 02:23:18.889 590 590 V RefreshRateConfigs: getSortedRefreshRateList: config 3 added to list policy
09-13 02:23:18.889 590 590 V RefreshRateConfigs: getSortedRefreshRateList: config 2 added to list policy
09-13 02:23:18.889 590 590 V RefreshRateConfigs: getSortedRefreshRateList: config 1 added to list policy
09-13 02:23:18.889 590 590 V RefreshRateConfigs: getSortedRefreshRateList: config 0 added to list policy
09-13 02:23:18.889 590 590 V RefreshRateConfigs: primary refresh rates: 50fps 60fps 90fps 120fps
09-13 02:23:18.890 590 590 V RefreshRateConfigs: getSortedRefreshRateList: config 3 added to list policy
09-13 02:23:18.890 590 590 V RefreshRateConfigs: getSortedRefreshRateList: config 2 added to list policy
09-13 02:23:18.890 590 590 V RefreshRateConfigs: getSortedRefreshRateList: config 1 added to list policy
09-13 02:23:18.890 590 590 V RefreshRateConfigs: getSortedRefreshRateList: config 0 added to list policy
09-13 02:23:18.890 590 590 V RefreshRateConfigs: app request refresh rates: 50fps 60fps 90fps 120fps
09-13 02:23:18.891 590 590 V SurfaceFlinger: Setting desired display config specs: defaultConfig: 0 primaryRange: [50 120] expandedRange: [0 120]
09-13 02:23:18.891 590 590 V RefreshRateConfigs: getRefreshRateForContent 0 layers
09-13 02:23:18.891 590 590 V SurfaceFlinger: trying to switch to Scheduler preferred config 3 (120fps)
09-13 02:23:18.891 590 590 V SurfaceFlinger: switching to Scheduler preferred config 3
09-13 02:23:18.891 590 590 V SurfaceFlinger: setDesiredActiveConfig(120fps)
09-13 02:23:18.892 590 737 V SurfaceFlinger: setDesiredActiveConfig(120fps)
09-13 02:23:18.893 590 590 V SurfaceFlinger: performSetActiveConfig changing active config to 3(120fps)
09-13 02:23:18.898 590 590 V SurfaceFlinger: performSetActiveConfig changing active config to 3(120fps)
09-13 02:26:05.924 1034 1087 I DisplayModeDirector: updateVoteLocked(displayId=0, priority=PRIORITY_APP_REQUEST_REFRESH_RATE, vote=Vote{width=-1, height=-1, minRefreshRate=60.0, maxRefreshRate=60.0})
09-13 02:26:05.924 1034 1087 I DisplayModeDirector: updateVoteLocked(displayId=0, priority=PRIORITY_APP_REQUEST_SIZE, vote=Vote{width=1080, height=2408, minRefreshRate=0.0, maxRefreshRate=Infinity})
09-13 02:26:05.928 590 590 V RefreshRateConfigs: getRefreshRateForContent 2 layers
09-13 02:26:05.928 590 590 V RefreshRateConfigs: refreshRate:50fps,50.00
09-13 02:26:05.928 590 590 V RefreshRateConfigs: refreshRate:60fps,60.00
09-13 02:26:05.928 590 590 V RefreshRateConfigs: refreshRate:90fps,90.00
09-13 02:26:05.928 590 590 V RefreshRateConfigs: refreshRate:120fps,120.00
09-13 02:26:05.928 590 590 V RefreshRateConfigs: Calculating score for NavigationBar0#0 (Max, weight 0.06)
09-13 02:26:05.928 590 590 V RefreshRateConfigs: NavigationBar0#0 (Max, weight 0.06) gives 50fps score of 0.17
09-13 02:26:05.928 590 590 V RefreshRateConfigs: NavigationBar0#0 (Max, weight 0.06) gives 60fps score of 0.25
09-13 02:26:05.928 590 590 V RefreshRateConfigs: NavigationBar0#0 (Max, weight 0.06) gives 90fps score of 0.56
09-13 02:26:05.928 590 590 V RefreshRateConfigs: NavigationBar0#0 (Max, weight 0.06) gives 120fps score of 1.00
09-13 02:26:05.928 590 590 V RefreshRateConfigs: Calculating score for com.youku.phone/com.youku.v2.HomePageEntry#0 (Max, weight 1.00)
09-13 02:26:05.928 590 590 V RefreshRateConfigs: com.youku.phone/com.youku.v2.HomePageEntry#0 (Max, weight 1.00) gives 50fps score of 0.17
09-13 02:26:05.928 590 590 V RefreshRateConfigs: com.youku.phone/com.youku.v2.HomePageEntry#0 (Max, weight 1.00) gives 60fps score of 0.25
09-13 02:26:05.928 590 590 V RefreshRateConfigs: com.youku.phone/com.youku.v2.HomePageEntry#0 (Max, weight 1.00) gives 90fps score of 0.56
09-13 02:26:05.928 590 590 V RefreshRateConfigs: com.youku.phone/com.youku.v2.HomePageEntry#0 (Max, weight 1.00) gives 120fps score of 1.00
09-13 02:26:05.928 590 590 V RefreshRateConfigs: 120fps scores 1.06
09-13 02:26:05.928 590 590 V RefreshRateConfigs: 90fps scores 0.60
09-13 02:26:05.928 590 590 V RefreshRateConfigs: 60fps scores 0.26
09-13 02:26:05.928 590 590 V RefreshRateConfigs: 50fps scores 0.18
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: displayId:0
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes:0
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:6
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:5
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes find priority:5, vote:Vote{width=-1, height=-1, minRefreshRate=0.0, maxRefreshRate=120.0}
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes before summary: min:0.0 max:Infinity height:-1 width: -1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-0 summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-1 summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:4
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes find priority:4, vote:Vote{width=1080, height=2408, minRefreshRate=0.0, maxRefreshRate=Infinity}
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes before summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-0 summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-1 summary: min:0.0 max:120.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:3
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes find priority:3, vote:Vote{width=-1, height=-1, minRefreshRate=60.0, maxRefreshRate=60.0}
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes before summary: min:0.0 max:120.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-0 summary: min:60.0 max:60.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-1 summary: min:60.0 max:60.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:2
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes find priority:2, vote:Vote{width=-1, height=-1, minRefreshRate=50.0, maxRefreshRate=Infinity}
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes before summary: min:60.0 max:60.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-0 summary: min:60.0 max:60.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-1 summary: min:60.0 max:60.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:0
09-13 02:26:05.940 1034 1086 W DisplayModeDirector: filterModes:{id=1, width=1080, height=2408, fps=50.0}
09-13 02:26:05.940 1034 1086 W DisplayModeDirector: Discarding mode 1, outside refresh rate bounds: minRefreshRate=60.0, maxRefreshRate=60.0, modeRefreshRate=50.0
09-13 02:26:05.940 1034 1086 W DisplayModeDirector: filterModes:{id=2, width=1080, height=2408, fps=60.0}
09-13 02:26:05.940 1034 1086 W DisplayModeDirector: filterModes:{id=3, width=1080, height=2408, fps=90.0}
09-13 02:26:05.940 1034 1086 W DisplayModeDirector: Discarding mode 3, outside refresh rate bounds: minRefreshRate=60.0, maxRefreshRate=60.0, modeRefreshRate=90.0
09-13 02:26:05.940 1034 1086 W DisplayModeDirector: filterModes:{id=4, width=1080, height=2408, fps=120.00001}
09-13 02:26:05.940 1034 1086 W DisplayModeDirector: Discarding mode 4, outside refresh rate bounds: minRefreshRate=60.0, maxRefreshRate=60.0, modeRefreshRate=120.00001
09-13 02:26:05.940 1034 1086 W DisplayModeDirector: Found available modes=[2] with lowest priority considered PRIORITY_DEFAULT_REFRESH_RATE and constraints: width=1080, height=2408, minRefreshRate=60.0, maxRefreshRate=60.0
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes:3
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:6
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:5
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes find priority:5, vote:Vote{width=-1, height=-1, minRefreshRate=0.0, maxRefreshRate=120.0}
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes before summary: min:0.0 max:Infinity height:-1 width: -1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-0 summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-1 summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:4
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes find priority:4, vote:Vote{width=1080, height=2408, minRefreshRate=0.0, maxRefreshRate=Infinity}
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes before summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-0 summary: min:0.0 max:120.0 height:-1 width: -1
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-1 summary: min:0.0 max:120.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes: priority:3
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes find priority:3, vote:Vote{width=-1, height=-1, minRefreshRate=60.0, maxRefreshRate=60.0}
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes before summary: min:0.0 max:120.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-0 summary: min:60.0 max:60.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: sumarizeVotes after-1 summary: min:60.0 max:60.0 height:2408 width: 1080
09-13 02:26:05.940 1034 1086 I DisplayModeDirector: App request range: [60 60]
09-13 02:26:05.976 590 590 D ha ha : #00 pc 00000000000ffdcc /system/lib64/libsurfaceflinger.so (android::scheduler::RefreshRateConfigs::constructAvailableRefreshRates()+176)
09-13 02:26:05.976 590 590 D ha ha : #01 pc 000000000010004c /system/lib64/libsurfaceflinger.so (android::scheduler::RefreshRateConfigs::setDisplayManagerPolicy(android::scheduler::RefreshRateConfigs::Policy const&)+464)
09-13 02:26:05.976 590 590 D ha ha : #02 pc 00000000001278d4 /system/lib64/libsurfaceflinger.so (android::SurfaceFlinger::setDesiredDisplayConfigSpecsInternal(android::sp<android::DisplayDevice> const&, std::__1::optional<android::scheduler::RefreshRateConfigs::Policy> const&, bool)+432)
09-13 02:26:05.976 590 590 D ha ha : #03 pc 00000000001383f0 /system/lib64/libsurfaceflinger.so (_ZNSt3__120__packaged_task_funcIZN7android14SurfaceFlinger28setDesiredDisplayConfigSpecsERKNS1_2spINS1_7IBinderEEEiffffE4$_63NS_9allocatorIS8_EEFivEEclEv$ed74649543c784cf7bf71a82a57ab79d+300)
09-13 02:26:05.976 590 590 D ha ha : #08 pc 000000000010db58 /system/lib64/libsurfaceflinger.so (android::SurfaceFlinger::run()+20)
09-13 02:26:05.976 590 590 V RefreshRateConfigs: constructAvailableRefreshRates: default 1 group -1 primaryRange=[60.00 60.00] appRequestRange=[60.00 60.00]
09-13 02:26:05.976 590 590 V RefreshRateConfigs: getSortedRefreshRateList: config 1 added to list policy
09-13 02:26:05.976 590 590 V RefreshRateConfigs: primary refresh rates: 60fps
09-13 02:26:05.976 590 590 V RefreshRateConfigs: getSortedRefreshRateList: config 1 added to list policy
09-13 02:26:05.976 590 590 V RefreshRateConfigs: app request refresh rates: 60fps
09-13 02:26:05.976 590 590 V SurfaceFlinger: Setting desired display config specs: defaultConfig: 1 primaryRange: [60 60] expandedRange: [60 60]
09-13 02:26:05.976 590 590 V RefreshRateConfigs: getRefreshRateForContent 2 layers
09-13 02:26:05.976 590 590 V RefreshRateConfigs: refreshRate:60fps,60.00
09-13 02:26:05.976 590 590 V RefreshRateConfigs: Calculating score for NavigationBar0#0 (Max, weight 0.06)
09-13 02:26:05.976 590 590 V RefreshRateConfigs: Calculating score for com.youku.phone/com.youku.v2.HomePageEntry#0 (Max, weight 1.00)
09-13 02:26:05.976 590 590 V RefreshRateConfigs: 60fps scores 0.00
09-13 02:26:05.976 590 590 V RefreshRateConfigs: layers not scored - choose 60fps
09-13 02:26:05.976 590 590 V SurfaceFlinger: trying to switch to Scheduler preferred config 1 (60fps)
09-13 02:26:05.976 590 590 V SurfaceFlinger: switching to Scheduler preferred config 1
09-13 02:26:05.976 590 590 V SurfaceFlinger: setDesiredActiveConfig(60fps)
09-13 02:26:05.977 590 590 V SurfaceFlinger: performSetActiveConfig changing active config to 1(60fps)
09-13 02:26:05.993 590 590 V SurfaceFlinger: performSetActiveConfig changing active config to 1(60fps)
09-13 02:26:05.995 590 590 I SurfaceFlinger: operator()(), mtkRenderCntDebug 79, screenshot (com.youku.phone/com.youku.v2.HomePageEntry#0)
09-13 02:26:06.102 590 590 I SurfaceFlinger: operator()(), mtkRenderCntDebug 80, screenshot (com.youku.phone/com.youku.v2.HomePageEntry#0)
adb shell settings put system min_refresh_rate 60 //改变的是primaryRange
adb shell settings put system peak_refresh_rate 120//改变的是appRequestRange
09-10 02:22:34.699 593 593 V RefreshRateConfigs: constructAvailableRefreshRates: default 0 group -1 primaryRange=[60.00 60.00] appRequestRange=[0.00 120.00]
09-10 02:22:34.699 593 593 V RefreshRateConfigs: getSortedRefreshRateList: config 0 added to list policy
09-10 02:22:34.699 593 593 V RefreshRateConfigs: primary refresh rates: 60fps
09-10 02:22:34.700 593 593 V RefreshRateConfigs: getSortedRefreshRateList: config 2 added to list policy
09-10 02:22:34.700 593 593 V RefreshRateConfigs: getSortedRefreshRateList: config 1 added to list policy
09-10 02:22:34.700 593 593 V RefreshRateConfigs: getSortedRefreshRateList: config 0 added to list policy
09-10 02:22:34.700 593 593 V RefreshRateConfigs: app request refresh rates: 60fps 90fps 120fps
09-10 02:22:34.700 593 593 V SurfaceFlinger: Setting desired display config specs: defaultConfig: 0 primaryRange: [60 60] expandedRange: [0 120]
09-09 12:02:57.170 583 583 V SurfaceFlinger: Setting desired display config specs: defaultConfig: 0 primaryRange: [0 60] expandedRange: [0 60]
09-09 12:02:57.264 583 583 D ha ha : #00 pc 0000000000103ed8 /system/lib64/libsurfaceflinger.so (android::Scheduler::getPreferredConfigId()+76)
09-09 12:02:57.265 583 583 D ha ha : #01 pc 0000000000127ba4 /system/lib64/libsurfaceflinger.so (android::SurfaceFlinger::setDesiredDisplayConfigSpecsInternal(android::sp<android::DisplayDevice> const&, std::__1::optional<android::scheduler::RefreshRateConfigs::Policy> const&, bool)+1108)
09-09 12:02:57.265 583 583 D ha ha : #02 pc 000000000013841c /system/lib64/libsurfaceflinger.so (_ZNSt3__120__packaged_task_funcIZN7android14SurfaceFlinger28setDesiredDisplayConfigSpecsERKNS1_2spINS1_7IBinderEEEiffffE4$_63NS_9allocatorIS8_EEFivEEclEv$ed74649543c784cf7bf71a82a57ab79d+300)
09-09 12:02:57.265 583 583 D ha ha : #03 pc 000000000012db5c /system/lib64/libsurfaceflinger.so (std::__1::packaged_task<int ()>::operator()()+88)
09-09 12:02:57.265 583 583 D ha ha : #04 pc 0000000000019ae8 /system/lib64/libutils.so (android::Looper::pollInner(int)+372)
09-09 12:02:57.265 583 583 D ha ha : #05 pc 000000000001990c /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+112)
09-09 12:02:57.265 583 583 D ha ha : #06 pc 00000000000fc7e0 /system/lib64/libsurfaceflinger.so (android::impl::MessageQueue::waitMessage()+84)
09-09 12:02:57.266 583 583 D ha ha : #07 pc 000000000010db84 /system/lib64/libsurfaceflinger.so (android::SurfaceFlinger::run()+20)
09-09 12:02:57.266 583 583 D ha ha : #08 pc 0000000000002398 /system/bin/surfaceflinger (main+848)
09-09 12:02:57.266 583 583 D ha ha : #09 pc 000000000004973c /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+108)
09-09 12:02:57.266 583 583 V RefreshRateConfigs: getRefreshRateForContent 0 layers
HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType(
scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals) {
ATRACE_CALL();
if (consideredSignals) *consideredSignals = {};
// If Display Power is not in normal operation we want to be in performance mode. When coming
// back to normal mode, a grace period is given with DisplayPowerTimer.
if (mDisplayPowerTimer &&
(!mFeatures.isDisplayPowerStateNormal ||
mFeatures.displayPowerTimer == TimerState::Reset)) {
return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
}
const bool touchActive = mTouchTimer && mFeatures.touch == TouchState::Active;
const bool idle = mIdleTimer && mFeatures.idleTimer == TimerState::Expired;
if (!mUseContentDetectionV2) {
// As long as touch is active we want to be in performance mode.
if (touchActive) {
return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
}
// If timer has expired as it means there is no new content on the screen.
if (idle) {
if (consideredSignals) consideredSignals->idle = true;
return mRefreshRateConfigs.getMinRefreshRateByPolicy().getConfigId();
}
// If content detection is off we choose performance as we don't know the content fps.
if (mFeatures.contentDetectionV1 == ContentDetectionState::Off) {
// NOTE: V1 always calls this, but this is not a default behavior for V2.
return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
}
// Content detection is on, find the appropriate refresh rate with minimal error
return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements)
.getConfigId();
}
return mRefreshRateConfigs
.getBestRefreshRate(mFeatures.contentRequirements, {.touch = touchActive, .idle = idle},
consideredSignals)
.getConfigId();
}
const RefreshRate& RefreshRateConfigs::getBestRefreshRate( const std::vector<LayerRequirement>& layers, const GlobalSignals& globalSignals, GlobalSignals* outSignalsConsidered) const { ATRACE_CALL(); ALOGV("getRefreshRateForContent %zu layers", layers.size()); if (outSignalsConsidered) *outSignalsConsidered = {}; const auto setTouchConsidered = [&] { if (outSignalsConsidered) { outSignalsConsidered->touch = true; } }; const auto setIdleConsidered = [&] { if (outSignalsConsidered) { outSignalsConsidered->idle = true; } }; std::lock_guard lock(mLock); int noVoteLayers = 0; int minVoteLayers = 0; int maxVoteLayers = 0; int explicitDefaultVoteLayers = 0; int explicitExactOrMultipleVoteLayers = 0; float maxExplicitWeight = 0; for (const auto& layer : layers) { if (layer.vote == LayerVoteType::NoVote) { noVoteLayers++; } else if (layer.vote == LayerVoteType::Min) { minVoteLayers++; } else if (layer.vote == LayerVoteType::Max) { maxVoteLayers++; } else if (layer.vote == LayerVoteType::ExplicitDefault) { explicitDefaultVoteLayers++; maxExplicitWeight = std::max(maxExplicitWeight, layer.weight); } else if (layer.vote == LayerVoteType::ExplicitExactOrMultiple) { explicitExactOrMultipleVoteLayers++; maxExplicitWeight = std::max(maxExplicitWeight, layer.weight); } } const bool hasExplicitVoteLayers = explicitDefaultVoteLayers > 0 || explicitExactOrMultipleVoteLayers > 0; // Consider the touch event if there are no Explicit* layers. Otherwise wait until after we've // selected a refresh rate to see if we should apply touch boost. if (globalSignals.touch && !hasExplicitVoteLayers) { ALOGV("TouchBoost - choose %s", getMaxRefreshRateByPolicyLocked().getName().c_str()); setTouchConsidered(); return getMaxRefreshRateByPolicyLocked(); } // If the primary range consists of a single refresh rate then we can only // move out the of range if layers explicitly request a different refresh // rate. const Policy* policy = getCurrentPolicyLocked(); const bool primaryRangeIsSingleRate = policy->primaryRange.min == policy->primaryRange.max; if (!globalSignals.touch && globalSignals.idle && !(primaryRangeIsSingleRate && hasExplicitVoteLayers)) { ALOGV("Idle - choose %s", getMinRefreshRateByPolicyLocked().getName().c_str()); setIdleConsidered(); return getMinRefreshRateByPolicyLocked(); } if (layers.empty() || noVoteLayers == layers.size()) { return getMaxRefreshRateByPolicyLocked(); } // Only if all layers want Min we should return Min if (noVoteLayers + minVoteLayers == layers.size()) { ALOGV("all layers Min - choose %s", getMinRefreshRateByPolicyLocked().getName().c_str()); return getMinRefreshRateByPolicyLocked(); } // Find the best refresh rate based on score std::vector<std::pair<const RefreshRate*, float>> scores; scores.reserve(mAppRequestRefreshRates.size()); for (const auto refreshRate : mAppRequestRefreshRates) { scores.emplace_back(refreshRate, 0.0f); } for (const auto& layer : layers) { ALOGV("Calculating score for %s (%s, weight %.2f)", layer.name.c_str(), layerVoteTypeString(layer.vote).c_str(), layer.weight); if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min) { continue; } auto weight = layer.weight; for (auto i = 0u; i < scores.size(); i++) { bool inPrimaryRange = scores[i].first->inPolicy(policy->primaryRange.min, policy->primaryRange.max); if ((primaryRangeIsSingleRate || !inPrimaryRange) && !(layer.focused && layer.vote == LayerVoteType::ExplicitDefault)) { // Only focused layers with ExplicitDefault frame rate settings are allowed to score // refresh rates outside the primary range. continue; } // If the layer wants Max, give higher score to the higher refresh rate if (layer.vote == LayerVoteType::Max) { const auto ratio = scores[i].first->fps / scores.back().first->fps; // use ratio^2 to get a lower score the more we get further from peak const auto layerScore = ratio * ratio; ALOGV("%s (Max, weight %.2f) gives %s score of %.2f", layer.name.c_str(), weight, scores[i].first->name.c_str(), layerScore); scores[i].second += weight * layerScore; continue; } const auto displayPeriod = scores[i].first->hwcConfig->getVsyncPeriod(); const auto layerPeriod = round<nsecs_t>(1e9f / layer.desiredRefreshRate); if (layer.vote == LayerVoteType::ExplicitDefault) { const auto layerScore = [&]() { // Find the actual rate the layer will render, assuming // that layerPeriod is the minimal time to render a frame auto actualLayerPeriod = displayPeriod; int multiplier = 1; while (layerPeriod > actualLayerPeriod + MARGIN_FOR_PERIOD_CALCULATION) { multiplier++; actualLayerPeriod = displayPeriod * multiplier; } return std::min(1.0f, static_cast<float>(layerPeriod) / static_cast<float>(actualLayerPeriod)); }(); ALOGV("%s (ExplicitDefault, weight %.2f) %.2fHz gives %s score of %.2f", layer.name.c_str(), weight, 1e9f / layerPeriod, scores[i].first->name.c_str(), layerScore); scores[i].second += weight * layerScore; continue; } if (layer.vote == LayerVoteType::ExplicitExactOrMultiple || layer.vote == LayerVoteType::Heuristic) { const auto layerScore = [&] { // Calculate how many display vsyncs we need to present a single frame for this // layer const auto [displayFramesQuot, displayFramesRem] = getDisplayFrames(layerPeriod, displayPeriod); static constexpr size_t MAX_FRAMES_TO_FIT = 10; // Stop calculating when score < 0.1 if (displayFramesRem == 0) { // Layer desired refresh rate matches the display rate. return 1.0f; } if (displayFramesQuot == 0) { // Layer desired refresh rate is higher the display rate. return (static_cast<float>(layerPeriod) / static_cast<float>(displayPeriod)) * (1.0f / (MAX_FRAMES_TO_FIT + 1)); } // Layer desired refresh rate is lower the display rate. Check how well it fits // the cadence auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem)); int iter = 2; while (diff > MARGIN_FOR_PERIOD_CALCULATION && iter < MAX_FRAMES_TO_FIT) { diff = diff - (displayPeriod - diff); iter++; } return 1.0f / iter; }(); ALOGV("%s (%s, weight %.2f) %.2fHz gives %s score of %.2f", layer.name.c_str(), layerVoteTypeString(layer.vote).c_str(), weight, 1e9f / layerPeriod, scores[i].first->name.c_str(), layerScore); scores[i].second += weight * layerScore; continue; } } } // Now that we scored all the refresh rates we need to pick the one that got the highest score. // In case of a tie we will pick the higher refresh rate if any of the layers wanted Max, // or the lower otherwise. const RefreshRate* bestRefreshRate = maxVoteLayers > 0 ? getBestRefreshRate(scores.rbegin(), scores.rend()) : getBestRefreshRate(scores.begin(), scores.end()); if (primaryRangeIsSingleRate) { // If we never scored any layers, then choose the rate from the primary // range instead of picking a random score from the app range. if (std::all_of(scores.begin(), scores.end(), [](std::pair<const RefreshRate*, float> p) { return p.second == 0; })) { ALOGV("layers not scored - choose %s", getMaxRefreshRateByPolicyLocked().getName().c_str()); return getMaxRefreshRateByPolicyLocked(); } else { return *bestRefreshRate; } } // Consider the touch event if there are no ExplicitDefault layers. ExplicitDefault are mostly // interactive (as opposed to ExplicitExactOrMultiple) and therefore if those posted an explicit // vote we should not change it if we get a touch event. Only apply touch boost if it will // actually increase the refresh rate over the normal selection. const RefreshRate& touchRefreshRate = getMaxRefreshRateByPolicyLocked(); if (globalSignals.touch && explicitDefaultVoteLayers == 0 && bestRefreshRate->fps < touchRefreshRate.fps) { setTouchConsidered(); ALOGV("TouchBoost - choose %s", touchRefreshRate.getName().c_str()); return touchRefreshRate; } return *bestRefreshRate;}