low fps rate

Started by peter, June 21, 2016, 11:03:44 PM

Previous topic - Next topic

peter

I am using jpct-ae to rendering over 400 3D objects at once. what FPS amount should I expect? right now I am getting 10fps on android 5.1 galaxy note4 , it's pretty low.

EgonOlsen

That's actually pretty good for 400 objects. Draw calls are expensive (for the hardware, not for the engine) and rendering 400 objects on a mobile device isn't really feasible with good performance. Try to reduce the number of objects or join them into several larger ones if possible.
What kind of scene is this that needs to display so many objects?

peter

I rendering some obj file in iPhone4 using scenekit, the performance in ios is much better than Android. I assume iPhone and Android phone should have similar performance since they are both using OpenGL 

EgonOlsen

iPhone always uses PowerVR graphic chips. Android uses either PowerVR, Mali, Adreno, nVidia,...they all have different characteristics. Some are more sensitive to draw calls (Adreno for example) then others. In addition, in higher object scenes, the CPU/GPU governor in some devices tends to keep the GPU clock low, because of...reasons.
Which Android device are we talking about here?

peter

I tested on Samsung tab 2 Android 4.4 , galaxy note4 Android 6.0.1, nexus 5 Android 5.1 and OnePlus 3 Android 6.0.1

peter

it also takes long time to get those objects show on screen, it's doing Creating buffers... and VBO created for object for all 3D objects. it's possible to do those when creating 3D Objects?

EgonOlsen

#6
No, it has to happen in the render thread. But if you don't use 400 individual objects, you can make them share mesh- and compiled data: http://www.jpct.net/wiki/index.php?title=Reducing_memory_usage#Reduce_memory_usage_of_objects

Edit: In addition, and in case you aren't doing it already, consider to use serialized objects instead of the raw 3d formats. That link above contains some Information about this as well.

EgonOlsen

#7
Quote from: peter on June 24, 2016, 05:34:00 PM
I tested on Samsung tab 2 Android 4.4 , galaxy note4 Android 6.0.1, nexus 5 Android 5.1 and OnePlus 3 Android 6.0.1
Except for the tab2, these are all Adreno powered devices and Adreno isn't really good when it comes to draw calls. That, and multiple draws of smaller objects seem to make the gpu governor think that it can get away with low gpu clock speeds. I have this problem in my RPG as well: In dungeons, which are rendered as many small wall and ceiling elements, it usually thinks that 180mhz is enough albeit it could go up to 600mhz. In the rare cases in which it does, performance easily triples. I tried to battle this behaviour, but it didn't work out...

peter

thank you for explaining. there is another problem I have with rendering 400 objects. when the App come back from Pause, jPct will redo all the creating buffer. it says "OpenGL context has changed(2)...recovering for renderer 2/1!" do you know how to prevent this? what does "OpenGL context has changed" mean?

EgonOlsen

It means that...the context has changed!? Or at least it doesn't know any better, so it acts as if it has. If the context changes, all data on the gpu will be lost and has to be retransfered. Context losses can happen when pausing/resuming an app, but they don't have to. You can improve the situation by doing what is mentioned in the last chapter of this post: http://www.jpct.net/forum2/index.php/topic,4549.msg31423.html#msg31423

peter

I did "mGLView.setPreserveEGLContextOnPause(true);" at onCreateView, the onSurfaceChanged still being called twice after resume

EgonOlsen

onSurfaceChanged() can be called as much as Android likes. I've seen the strangest things happening there. It has nothing to do with the state of setPreserveEGLContextOnPause(). Keep in mind that setting setPreserveEGLContextOnPause(true) is one only part of the solution. You have to check the actual context as well, as mentioned in the thread.

peter

To solve low fps problem, I tried merge 477 objects into one large object, after that I got 60 fps. just wondering why it solved the problem?

AGP

 Well, he said that it's because of the number of draw calls, and that Adreno is bad at it. But I'd also like a more detailed explanation. ; )

EgonOlsen

There's actually not much to explain. Draw calls are one of the most expensive operations that you can do in graphics. Different devices behave different, of course, but they all benefit from reducing draw calls.
Another related issue is the GPU governor on Android. That's the part of the OS that takes care of GPU clock rate and such. From my observations, this code tends to up the clock rate only (again, this depends on the device/OS) if the GPU processes larger chunks of geometry. If it processes the same amount of vertices but splitted into smaller objects, the clock rate stays lower, which reduces performance even more.