As I step through my code using F8, after setting a breakpoint, I don't understand how there is code running while the code should be stopped. It is an Android 3D game, and even though the code is stopped, there is a graphics object rotating in the background as if it is in a separate thread from the code that I am debugging or something.
The game code is huge, and there isn't really any point in showing any code, but if there are any specific questions about the code I can either answer it or show some snippet.
Very strange. Any ideas anyone?
[EDIT] I am using Java and Opengl ES 2.0. No third party software.
The code has one thread that I created to handle audio record data.
The main activity has an onTouchEvent() background thread which gets called when an touch event occurs, but that code only processes input data as it occurs, and I don't touch the screen during this particular debug.
The activity also of course has the opengl onDrawFrame() thread which runs all game logic. I suppose there is a good chance this is where the problem lies.
With Opengl ES apps should game logic be run in a separate thread from the render loop? I think thread would be huge, and there would be a similar problem... graphics code executing in a thread while trying to single step through code in the debugger.
Maybe there is a way for threads to be force stopped when running in Android Studio?
[/EDIT]
Related
I am trying to find the UI rendering time for each Activity in android. I come to know that can analyses the performance using of systrace or perfetto. But the problem is find the UI rendering part from that huge graph. Can any one help me to find the UI rendering time from systrace or perfetto.
System Trace includes data from all processes running on the device, so first you need to find the relevant processes. Here's a couple of places to get you started:
Your app process. The name should look like com.your.app. Expand that process and then you want to focus on the main thread (same name as the process name) and a thread called RenderThread.
Screenshot of the RenderThread and main thread in Android Studio
The SurfaceFlinger process. It's a process running on Android devices, responsible for compositing surfaces to the display. Expand that process and look for its main thread and a myriad of counters (e.g. VSYNC, SurfaceView) to help you troubleshoot rendering issues.
Screenshot of SurfaceFlinger counters in Perfetto
To know exactly what's causing the UI rendering issue requires knowledge of how your app works and some trial-and-error. These videos might help you:
Performance Analysis Using Systrace: https://youtu.be/9kNhB_z704I
Troubleshooting app performance issues with System Trace in Android Studio
(this one focuses on Android Studio): https://youtu.be/EjmIit_amnE
Debugging Application Performance (this one is bit old and still uses the legacy systrace tool)
: https://youtu.be/qXVxuLvzKek
I am a mediocore android developer for years. I like android but there's a big problem; frame drops. Even the most powerful ones can stutter so frequently while IOS devices can run at constant 60fps. I just can't understand why. I want to know it. So first thing i did was watching an I/O presentation about performance. And i didn't really understand one thing. Why can't ui and render thread run at the same time ? Yeah i know the basics like render thread can't know what to render while ui thread is doing it's thing but why can't render thread render the frame before? You can see the video here:
https://youtu.be/9HtTL_RO2wI?t=491
And here's a diagram what am i asking for:
You get the idea. I don't know about low level things about android, can anyone explain this like i'm five.
Your process' main thread is responsible for the rendering of the frames that will be presented to the user, so you should keep the code running there as fast and light as possible. If you have to do some heavy processing or access any IO (network, sdcard, etc) that may impact on the fluidity of the application since the thread may be waiting for a response.
As a good practice you should start that IO access/heavy processing on another thread to run in background and let the system decide the priority to run it, if necessary is recommended to present some feedback to the user like a ProgressBar or something to indicate that something is being processed.
Also, the Render Thread need to know what to render before it does it, so the UI Thread have to process which information the app would like to present to the user.
As #JonGoodwin points out, they both run in parallel, but usually in two cores of the same processor, as nowadays phones have at least two cores. Both threads are run in CPU, where RenderThread sends rendering commands to the GPU. Notice that this is true since API 21 (RenderThread is what enables things like ripple effect).
The problem, though, is what #LucianoFerruzzi points out: usually poor code that does too many things in the UI thread (RenderThread is not accessible, at least not with standard mechanisms).
Also, see the following episode of Android Developers Backstage: Episode 74: Graphics
I have imported into Eclipse Juno the sample of OpenCv4Android, ver. 2.4.5, called "cameracontrol". It can be found here:Camera Control OpenCv4Android Sample.
Now I want to use this project as base for mine. I want to process every frame with image-processing techniques, so, in order to improve performance, I want to split the main activity of the project in two classes: one that is merely the activity and one (a thread) that is responsible for preview.
How can I do? Are there any examples about this?
This might not be a complete answer as I'm only learning about this myself at the moment, but I'll provide as much info as I can.
You will likely have to grab the images from the camera yourself and dispatch it to threads. This is because your activity in the example gets called with a frame from the camera and has to return the frame to be displayed (immediately) as the return value. You can't get 2+ frames to process in parallel without showing a blank screen in the meantime or some other hacky stuff. You'll probably want to allocate a (fixed sized) buffer somewhere, then start processing a frame with a worker thread when you get one (this would be the dispatcher). Once your worker thread is done he notifies the dispatcher who gives the image to the view. If frames come from the camera while all worker threads are busy (i.e. there are no free slots in the buffer), the frame is dropped. Once a space in the buffer frees up again, the next frame is accepted and processed.
You can look at the code of the initialitzeCamera function of JavaCameraView and NativeCameraView to get an idea of how to do this (also google should help, as this is how apps without OpenCV have to do it as well). For me the native camera performs significantly better though (even without heavy processing it's just much smoother), but ymmv...
I can't help with actual details about the implementation since I'm not that far into it myself yet. I dope this provides some ideas though.
I am porting my game, from iOS to Android. Mostly, it's working just fine. I'm mostly using C/C++ code, with the NDK / JNI, and a little Java to manage the app life-cycle and send touches and accelerometer info to my game.
As far as I can tell, there are 2 threads, the main UI thread, and a thread created by GLSurfaceView to handle display and flipping OpenGL back-buffers etc.
So, all is working well, apart from the touches. They feel sluggish and unresponsive, compared to other apps I have tried on my devices. After doing some research, I believe the issue may relate to how I am using threads. Specifically, I think, it could be related to not sleeping the display thread after it does it's work, and so, it's holding things up on the main UI thread. Does that sound plausible?
I tried computing how many ms I need the GLSurfaceView display thread to sleep, and then sleep(), and it improves the touches, but the animation is no longer a constant 60FPS on my devices. My suspicion is that I am computing the number of ms to sleep for the previous frame, and using that number to sleep for the current frame.
Or, it could be something altogether different? I don't know. I'm still very new to Android...
Hope someone can shed some light on the matter, or point me in the right direction.
Thanks,
You don't have to sleep the GL thread. In fact, I'd say sleeping the GL thread would make it even more sluggish since it's the thing rendering the images on the screen.
Sluggish UI is caused primarily by the main UI thread being held up. If you're doing a lot of processing on the main thread (accelerometer data for example), the main thread will have to do the work first and THEN handle your user input. This can give the "feeling" of sluggishness. All touch events and non-opengl drawing events must happen in the UI thread. Anything else can occur in a background thread which wouldn't block the UI thread for an extended period of time.
Aside from that, the other possibility is you're simply overloading the processor. Your GL thread might be taking a long time to draw. It's probably receiving and handling touch events and accelerometer data. However, if the render takes a really long time, then you'd be seeing out-dated data. Thus, it again feels "sluggish". You mentioned that it's not a constant 60 FPS so this is a very real possibility. You may have optimize your drawing code so the render is faster.
In the Android examples, like LunarLander, and many other tutorials written on blogs across the net, game loops almost always run a separate thread to call the state updating and rendering parts of the game.
Why is this? What are the advantages and disadvantages? The only reason I can think of is just to keep the app responsive to input such as if the user presses the menu or back buttons. Other than that, the game just has to chug along in update/render cycles as fast as it can.
I'm aware this is a good reason, although one would hope that if one's game is running at a decent frame rate, the app would remain responsive enough. But, are there any other reasons?
On the other hand, I imagine it would create more headache accessing game resources, for example a game object manager or the sound system, which may live on a separate thread.
On Lunar lander and other android apps - it is important to have your surface view run on a separate thread, so that the android OS does not kill it for any long running processes.
Android keeps the main UI thread - used for the menu and home buttons among other things - avaiable to recveive user input at all times. If you app causes the main thread to slow down, the OS will kill your thread and end you game.
So running your game loop off of the Surface View thread lets you game run as fast as it can when it has focus, but it also makes it possible for android to interrupt it whenever it needs to, for instance when a call come in, or the user presses the home button.