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
Related
I am trying to understand the Android (7) Graphics System from the system integrators point of view. My main focus is the minimum functionality that needs to be provided by libegl.
I understand that surfaceflinger is the main actor in this domain. Surfaceflinger initialized EGL, creates the actual EGL surface and acts as a consumer for buffers (frames) created by the app. The app again is executing the main part of required GLES calls. Obviously, this leads to restrictions as surfaceflinger and apps live in separate processes which is not the typical use case for GLES/EGL.
Things I do not understand:
Do apps on Android 7 always render into EGL_KHR_image buffers which are send to surfaceflinger? This would mean there's always an extra copy step (even when no composition is needed), as far as I understand... Or is there also some kind of optimized fullscreen mode, where apps do directly render into the final EGL surface?
Which inter-process sharing mechanisms are used here? My guess is that EGL_KHR_image, used with EGL_NATIVE_BUFFER_ANDROID, defines the exact binary format, so that an image object may be created in each process, where the memory is shared via ashmem. Is this already the complete/correct picture or do I miss something here?
I'd guess these are the main points I am lacking confident knowledge about, at the moment. For sure, I have some follow-up questions about this (like, how do gralloc/composition fit into this?), but, in accordance to this platform, I'd like to keep this question as compact as possible. Still, besides the main documentation page, I am missing documentation clearly targeted at system integrators. So further links would be really appreciated.
My current focus are typical use cases which would cover the vast majority of apps compatible with Android 7. If there are corner cases like long deprecated compatibility shims, I'd like to ignore them for now.
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.
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.
in some android test devices, when rendering in opengl 2.0 ES, the screen flashes.
I was able to track the problem to the GLSurfaceView class at the point the "eglSwapBuffers" is called, so the flashing is produced on each iteration, on one the screen becomes black and the next has the image I've drawn. So it seams that eglSwapBuffers is not preserving the back buffer on each call producing this flashing behaviour.
Is there anyway to preserve the back buffer? I've found around that maybe I could use the EGL_SWAP_BEHAVIOR_PRESERVED_BIT flag but I can't figure it out how to put it in android, and neither how to use it in old API's such as gingerbread.
Thanks
You should not need to modify GLSurfaceView. It's much more likely that your problem is caused by the drivers or configuration of your system. I would try a different test device with different graphics drivers. What happens when you run it on an AVD?
It could be that your test device is not making enough memory available to the underlying linux framebuffer device to get the normal triple buffering. Most systems will fall back to single buffering in that case. I recommend that you check these fb device parameters. The virtual_size should be large enough for 2 or 3 buffers for the display mode you are using:
cat /sys/class/graphics/fb0/mode
U:1024x768p-60
cat /sys/class/graphics/fb0/virtual_size
800,1440
Hi I was researching the possibility to transport the "not rendered" rendering calls to a second screen from Android. While researching I found out that Skia is behind the Surfacefinger, and the Canvas.draw() method. So my question is now, what would be the best interception point to branch off the calls in order to use them for a second screen / machine. The second device mut not be a pure replay device, but can be another Android device.
First I used VNC for that concept, but quickly found out that it badly performs, due to the double buffering effect, it is also possible to manipulate the android code in a sense that it omits the double buffering, but it is still of interest to actually use the pre rendered calles on a second, maybe scaled device.
Thanks