Hello,
I've been using Gio to make a small personal app on Android, and Gio
really made things easy and enjoyable to build.
On this adventure, it turned out that some phone manufacturers limit
screen refresh rate to 60hz when they see a SurfaceView, and that
results in Gio apps having less smooth scrolling/animation than the rest
of the system. If I were to guess the reasoning behind it, SurfaceView
is mainly used by games, where higher refresh rate can consume more
battery.
I published a module that can set the refresh rate back to high, and
contributors on Slack expressed interest in including this functionality
in gio-core. The question would be, what API to provide.
https://github.com/ilidemi/giorefreshrate
The simplest option would be to cover the main use case of smooth
scrolling with app.NewWindow(app.HighRefreshRate, ...) that picks the
highest refresh rate supported at the current resolution when the window
is created. This is similar to what the module currently does. On my
device (OnePlus 8 Pro, Android 13) it also plays nice with battery saver
mode or system-wide 60hz setting.
A more thorough option would be to allow the user to enumerate supported
display modes, run some logic to choose the best one and set the display
mode. Others suggested ViewEvent or ConfigEvent could be used to
communicate the options to the user. Concerns here are that not all apps
need it (on my device it takes 26 JNI method calls to enumerate and 5 to
set), setting the frame rate is only possible once the window is in
running state, and using a cross-platform event opens the door to having
to figure this out for other platforms that don't really need it. I also
think the main use case of smooth scrolling should remain a one-liner.
Would be curious if there are other opinions and if it's indeed a
functionality that should be in the core.
Regards,
Ilia
On Wed, 12 Apr 2023 at 15:25, Ilia Demianenko <ilia.demianenko@gmail.com> wrote:
>> Hello,>> I've been using Gio to make a small personal app on Android, and Gio> really made things easy and enjoyable to build.>> On this adventure, it turned out that some phone manufacturers limit> screen refresh rate to 60hz when they see a SurfaceView, and that> results in Gio apps having less smooth scrolling/animation than the rest> of the system. If I were to guess the reasoning behind it, SurfaceView> is mainly used by games, where higher refresh rate can consume more> battery.>> I published a module that can set the refresh rate back to high, and> contributors on Slack expressed interest in including this functionality> in gio-core. The question would be, what API to provide.> https://github.com/ilidemi/giorefreshrate>> The simplest option would be to cover the main use case of smooth> scrolling with app.NewWindow(app.HighRefreshRate, ...) that picks the> highest refresh rate supported at the current resolution when the window> is created. This is similar to what the module currently does. On my> device (OnePlus 8 Pro, Android 13) it also plays nice with battery saver> mode or system-wide 60hz setting.>> A more thorough option would be to allow the user to enumerate supported> display modes, run some logic to choose the best one and set the display> mode. Others suggested ViewEvent or ConfigEvent could be used to> communicate the options to the user. Concerns here are that not all apps> need it (on my device it takes 26 JNI method calls to enumerate and 5 to> set), setting the frame rate is only possible once the window is in> running state, and using a cross-platform event opens the door to having> to figure this out for other platforms that don't really need it. I also> think the main use case of smooth scrolling should remain a one-liner.>> Would be curious if there are other opinions and if it's indeed a> functionality that should be in the core.
An even simpler option is to automatically select the highest refresh
rate. As you
argue, Gio is designed for responsive UIs and not games.
If anything, a future option should be for *limiting* refresh rate in case you
have long running animation or other special needs.
WDYT?
Elias
That does sound like a good option. My only worry would be the time
taken by extra JNI calls at the startup.
I did some tests to see the impact, measuring the time between the
StageEvent with Stage=Running and the first FrameEvent, picking the
median of 10 runs.
OnePlus 8 Pro (2020 flagship) took 0.1ms without giorefreshrate and
0.7ms with, which isn't ideal but makes for a much better experience.
Moto G Pure (60hz budget phone) took 0.2ms without giorefreshrate and
5.2ms with, without really needing it. Rearranging the calls to bail
early if the display only supports one mode brought it down to 1.2ms
which is also not ideal but better. 0.3-0.4ms out of these are taken
by initializing the JVM and will likely go away when merged into core.
I can submit the change within a couple of days to make it default if
the perf cost sounds acceptable or as opt-in otherwise.
-Ilia
Instead of calling using JNI, it's not possible to do all the work on Java,
and then do a single JNI call? In that case, modify the current
`GioActivity.java`, or similar, and then call the new function using JNI.
--
Lucas Rodrigues
inkeliz@inkeliz.com
On Sun, Apr 16, 2023, at 8:02 AM, Ilia Demianenko wrote:
> That does sound like a good option. My only worry would be the time> taken by extra JNI calls at the startup.>> I did some tests to see the impact, measuring the time between the> StageEvent with Stage=Running and the first FrameEvent, picking the> median of 10 runs.>> OnePlus 8 Pro (2020 flagship) took 0.1ms without giorefreshrate and> 0.7ms with, which isn't ideal but makes for a much better experience.>> Moto G Pure (60hz budget phone) took 0.2ms without giorefreshrate and> 5.2ms with, without really needing it. Rearranging the calls to bail> early if the display only supports one mode brought it down to 1.2ms> which is also not ideal but better. 0.3-0.4ms out of these are taken> by initializing the JVM and will likely go away when merged into core.>> I can submit the change within a couple of days to make it default if> the perf cost sounds acceptable or as opt-in otherwise.>> -Ilia