Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Implement rate limiting to 30 fps #2931

Closed
ljbade opened this issue Nov 4, 2015 · 11 comments
Closed

Implement rate limiting to 30 fps #2931

ljbade opened this issue Nov 4, 2015 · 11 comments
Labels
Android Mapbox Maps SDK for Android performance Speed, stability, CPU usage, memory usage, or power usage

Comments

@ljbade
Copy link
Contributor

ljbade commented Nov 4, 2015

To improve performance and smoothness of the map we should rate limit to 30 fps as we now do on iOS.

The background from @adam-mapbox is in #1975 and #2922

To achieve similar results as iOS we will have to use Choreographer or postOnAnimation

/cc @bleege @tobrun @zugaldia

@ljbade ljbade added performance Speed, stability, CPU usage, memory usage, or power usage Android Mapbox Maps SDK for Android labels Nov 4, 2015
@ljbade ljbade added this to the android-v2.3.0 milestone Nov 4, 2015
@adam-mapbox
Copy link
Contributor

Apparently our minimum API is 15, and Choreographer appears to be API level 16. So one of those would have to bend. We could always use Choreographer all the way down to 16 and just "do our best" on API level 15.

Other than that, though, Choreographer looks like exactly what we need. I'll dig into it.

@bleege
Copy link
Contributor

bleege commented Nov 9, 2015

Good stuff! If we think that Choreographer is going to be the long term answer let's run at that first and see if it does indeed solve the problem for 16+. If it does then we can always revisit supported Android API levels.

Speaking of which, as of today http://developer.android.com/about/dashboards/index.html gives the following marketshare report (ie, dropping 15 could be doable via a 3.x.x release):

screen shot 2015-11-09 at 11 51 44 am

@ljbade
Copy link
Contributor Author

ljbade commented Nov 9, 2015

@adam-mapbox the Android docs do not proceed much detail on when TextureView will update the screen buffer. However I have been right though the source code for it and basically it selects the most recent rendered texture surface each time it is told by android framework to paint it's view. This might be from the same frame period or the previous one depending on how long GL takes to render and whether we start rendering before or after Texture View. In my experiments Choreograph did for before TextureView so if more a case of how long we take to render.

As for below API 16 you can use postOnDelay but as it is my as accurate there will be more jitter. However Android's animation system before 16 also suffered this problem anyway.

@bleege
Copy link
Contributor

bleege commented Nov 9, 2015

I worked with @adam-mapbox earlier today to create the Manual Zoom Activity in the TestApp as a place he can use to experiment with this issue on. See #2991 for PR.

@ljbade
Copy link
Contributor Author

ljbade commented Nov 10, 2015

@bleege nice!

A trick I discovered to detect skipped frames was to rotate the map 90 degrees each frame. I was then able to capturea video and step it frame by frame. It revealed every second frame skipped and also helped me get the GPS dot synced with the map.

@adam-mapbox
Copy link
Contributor

@bleege @kkaefer @incanus @ljbade

OK, so, following on the work that @bleege was helping with, I did some investigation of how to ensure that our Android framerate is smooth, but I got much more conflicting/inconsistent answers than I did on iOS (where the problem was obvious). I couldn't reproduce any kind of the extreme stuttering and sadness that was easy to reproduce on iOS. But I plowed ahead anyway, looking through docs. I found something that seemed promising, which was the method postInvalidateOnAnimation. Quoting from the docs: Cause an invalidate to happen on the next animation time step, typically the next display frame.. And Android suggests this function as follows: To post a call to invalidate() to occur once at the beginning of the next display frame, use postInvalidateOnAnimation().

The only thing is, it had the opposite effect. It seemed to visually make things worse, and also, in looking at the timing, I got much more inconsistent results. With postInvalidate, every frame time is an even multiple of 1/60 of a second (good). But with postInvalidateOnAnimation, we get frame times that are basically all over the place (bad).

Then I noticed this line in the docs for Choreographer: To ensure that the contents of a View scroll smoothly and are drawn in sync with display frame rendering, do nothing. This already happens automatically.. So...this implies to me that Android is doing something to sync things up with the frame interval, even if we set eglSwapInterval(0). But I'm not at all sure of what I'm seeing and it would be great to get confirmation from somebody who knows more Android. At this point the docs seem to kind of be contradicting themselves.

@ljbade
Copy link
Contributor Author

ljbade commented Nov 11, 2015

I imagine things are getting messy due to TextureView.

@adam-mapbox a very useful tool that is worth learning is systrace
https://developer.android.com/tools/performance/systrace/index.html
https://developer.android.com/tools/debugging/systrace.html
https://developer.android.com/tools/help/systrace.html

You can even add custom markers in Java and C++ to help clarify what is happening on the two different render threads (the C++ TextureView one and the Java application one)

@adam-mapbox
Copy link
Contributor

@incanus @ljbade @kkaefer

I investigated further by using my own personal Nexus 7 (with @incanus' help) and testing on there. Of course that device was slower, but it wasn't choppy, not in the way that iOS was. And the frame times are very consistent. I don't know if it's TextureView, or Choreographer, or what, but somebody is already locking us down to even frame times.

So I think that, unless someone feels motivated to investigate this further, I'm going to close this out for now. I wasn't able to identify anything obviously wrong on Android, like we were on iOS. I learned some useful things from doing this investigation and I'm going to leave this here for the future, in case we do start to see issues. But I'm not seeing the kind of thing that I saw on iOS.

@incanus
Copy link
Contributor

incanus commented Nov 11, 2015

Sounds reasonable @adam-mapbox 👍

@bleege
Copy link
Contributor

bleege commented Nov 12, 2015

Great! Thanks for checking this out @adam-mapbox.

You should still commit any changes you made to 2931-adams-playground and merge #2991 into master so that we can use this for regression testing in the future.

@adam-mapbox
Copy link
Contributor

OK!

On Wed, Nov 11, 2015 at 4:13 PM, Brad Leege notifications@github.com
wrote:

Great! Thanks for checking this out @adam-mapbox
https://github.com/adam-mapbox.

You should still commit any changes you made to 2931-adams-playground
https://github.com/mapbox/mapbox-gl-native/compare/2931-adams-playground
and merge #2991 #2991
into master so that we can use this for regression testing in the future.


Reply to this email directly or view it on GitHub
#2931 (comment)
.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Android Mapbox Maps SDK for Android performance Speed, stability, CPU usage, memory usage, or power usage
Projects
None yet
Development

No branches or pull requests

5 participants