I'd like to know the performance of my app, particularly the rendering time of video frames. I'm aware of DDMS in Eclipse->DDMS Perspective->System Information->Frame Render Time. However, as has been asked in this other question, the rendering information doesn't seem to show up even when you 'Update from Device' while the app is running.
After some research, I came across this command from this blog and this other one:
adb shell dumpsys gfxinfo <package-name>
However, when I run that command, it completes running right away and I get an output that looks like this, in part:
That is, I do not get more than one line of profile data (often the result is empty). What can I do to obtain more than one point of data in order to graph it? Or, what other alternatives should I consider to assess the rendering performance of the application?
The correct tool is systrace (basic docs, verbose docs). You will need a device that supports it, and will need root for some of the more useful bits.
You can see what every thread is doing, and much of the graphics stuff is instrumented. I don't think the video codecs themselves are typically instrumented, so you won't be able to see hardware codec decode times, but you can see the buffers move through the system.
Most of the interesting stuff will happen in mediaserver or SurfaceFlinger, so you won't see decoding / rendering activity appear in method profiling for your app.
Related
Is there a possibility to debug the shaders (fragment and vertex) in an Android Application with OpenGL-ES 2?
Since we only pass a String with code and a bunch of variables to replace with handles, it is very tedious to find the proper changes that need to be done.
Is it possible to write to the Android Log, as in Log.d()
Is it possible to use break points and to inspect the current values in the shader calculations?
I am simply not used to write code with a pen anymore and that's what it feels like to code within the shader text code.
This is an old question but since it appears first in searches and the old answer can be expanded upon, I'm leaving an alternative answer:
While printing or debugging like we do on Java or Kotlin is not possible, this doesn't mean that it cannot be debugged. There used to be a tool on the now deprecated Android Monitor for letting you see a trace of your GPU execution frame by frame, which included inspecting calls and geometry.
Right now the official GPU debugger is the Android GPU Inspector, which has some useful performance metrics and will include debugging frame by frame in a future update.
If the Android GPU Inspector doesn't have what you need, you can go with vendor-specific debuggers depending on your device (Mali Graphics Debugger, Snapdragon Debugger, etc.)
No. Remember that the GPU is going to execute every program millions of times (once per vertex, and once per fragment), often with hundreds of threads running concurrently, so any concept of "connect a debugger" is pretty much impossible.
Recently, I have started using dumpsys SurfaceFlinger to gather some information about android graphics. I currently work on a development board called Odroid-XU3. The display is a Dell monitor which is connected to the board through HDMI cable.
In the very last few lines of the output of the above command, I have two displays, while I only expect to have one. One of them is Display[0] and the other one is Display[1]. The type column of each of the displays could be HWC or GLES. Some times they are both HWC or GLES and some other times one is HWC and the other one is GLES.
What is the difference between Display[0] and Display[1]?
I have tried to find a documentation to understand how to interpret the output of the aforementioned command, but I have not found anything useful.
It would help to have the dumpsys output in your question, but I can make a couple of general observations.
display[0] is the device's built-in display. display[1] is an "external" display, in your case HDMI. These two indices are hard-wired. (Well, they were as of KitKat; I don't know if they've since un-hard-wired things.) Virtual displays start at index 2.
The chunk of text below the display is the hardware composer dump. It displays the layers on the screen, with a bunch of information about the position, rotation, and format of each layer.
The closest thing to documentation can be found in the HWC section of the graphics architecture doc. Given the level of the system you're working with, I would recommend you read the entire document. Beyond that, you can try to discern the meaning from the source code.
The arch doc does explain the difference between "HWC" and "GLES" in the output: "HWC" means the surface lives on a display overlay, while "GLES" means the surface is being composed with the GPU instead.
I'm trying to use the output of systrace to detect janky scrolling during automated tests: I want to notice it early, without having to sit there watching.
I spent some time trying to fathom the trace, and found this ebook very helpful: https://www.safaribooksonline.com/library/view/high-performance-android/9781491913994/ch04.html
The most promising hypothesis was checking whether VSYNC-sf ever stopped ticking on phones displaying VSYNC-sf.
On other machines, SurfaceFlinger seems to be started by either HW_SYNC_0 or VSYNC (sometimes one or both of those VSYNCs stop) but SurfaceFlinger also seems to be involved with VsyncOn, which sometimes appears to keep track of whether there are activity buffers outstanding, and sometimes whether there are input events that need delivering. Confusingly, sometimes input events are delivered during half-second pauses when there's no surface flinger activity, no application drawing, and when even the VSYNC and HW_VSYNC signals decide to pause.
Does anyone know what's going on there?
Should I simply expect to see Surface Flinger always busy - not alternately busy and idle with each tick - and always aligned with one or other of the VSYNCs?
I also sometimes see SurfaceFlinger taking longer than a tick to complete its processing - is that the application's fault for having a very complicated display, or is it just something that happens because some queue isn't empty enough?
I'd prefer to miss a possible jank than claim to have found one which isn't there.
Thanks!
Testing Display Performance Lists how to use the new framestats command from dumpsys to get this type of information. It will provide information on what frames you've missed, and how many of them you've missed.
It's also worth noting that SurfaceFlinger isn't always busy. It's only active when part of the screen needs to be updated. If nothing on the screen needs updating, then no new rendering occurs, and such, SurfaceFlinger should be idle.
You can get a bigger-picture view of the Android rendering pipeline with the Rendering Performance 101 video from Android Performance Patterns.
I have a report that my app makes certain devices reset (reboot).
I have no idea how can an app possibly make a device reset (I don't use the Admin classes, and don't have that permission).
The app involves standard UI + JNI calls + some OpenGL ES 2 rendering.
My best guess is that a GLSL shader freaks out the device...
When a device resets it erases its LogCat buffer as well.
Any advice on what and where to look for?
Most likely you are right regarding that it's something using OpenGL. However, there is also some probability that it's something related to JNI (especially, if you are doing something beyond the basic calls).
I think the only way of actions is following:
gather info on which devices, OS version it happens
get a device to reproduce it or get in touch with a user who can do some testing for you
prepare a version which logs to a file (and dont' forget to flush a file after each line of log, else reset will kill a buffered logs)
wrap all suspicious places into logs
I have an android app that is getting fairly large and complex now, and it seems to have intermittent performance problems. One time I will run the app and it's fine, another time it will struggle when switching views.
How can I detect the causes of the performance problem using debugging tools so that I may correct it?
Use the ddms tool which comes with the SDK. It has a nice feature called Allocation Tracker that allows you to see in real time how much memory your code is consuming and what specific line is causing that.
Most of the cases your app will slow down because of bad adapter implementations, poor layout inflation techniques or not using a cache system to decode Bitmaps (such as using SoftReference).
Take a look at this article for a brief explanation: Tracking Memory Allocations
In addition to the tool Cristian mentioned, Traceview is another helpful one. It's not very well documented but it can give you information about how often methods are being called, and which methods are taking a lot of time.
Another good memory tracking tool is MAT, here is a page that describes how to use it with Android: http://ttlnews.blogspot.com/2010/01/attacking-memory-problems-on-android.html
Both the tracing and the heap dumps can be done through the DDMS panel, if you prefer not to work with the command line. In Eclipse, in the devices panel, under the device/emulator you are using, click on your app (listed by package name), and you can then Start/Stop Method Profiling to get a trace and you can use Dump HPROF to get a heap dump. Note, the dumps need to be converted to work with the MAT plugin. The attacking-memory-problems-on-android above describes how to do that.