Support => NGUI 3 Support => Topic started by: madturtle84 on August 19, 2016, 04:04:00 PM
Title: DrawCall Rebuild Causing Performance Issue
Post by: madturtle84 on August 19, 2016, 04:04:00 PM
Hello,
I'm working on a ScrollView which has about 100 "Cards" stored in a UIGrid, and each card has a unique UITexture. Right now we hit a big performance issue and the bottleneck seems to be UIPanel.FillAllDrawCalls. Here is what I see after some debugging:
1. When I start dragging, FillAllDrawCalls() is called because FindDrawCall() for off-screen widget return null and set mRebuild to true.
2. When I stop dragging, UpdateSelf() removes all drawcall for off-screen widget.
As I keep dragging, Step 1 and 2 keeps repeating, therefore there's always a noticable lag at the beginning of the drag. On our targeted Android device FillAllDrawCalls() takes almost 1 second to complete, which make users think it's not draggable. ( Although the performance during drag is okay)
Here is my setting for Scrollview / Panel : (http://e66.imgup.net/ScreenShot447d.png)
Is there anything I can do to improve the performance?
Title: Re: DrawCall Rebuild Causing Performance Issue
Post by: ArenMook on August 20, 2016, 02:23:22 PM
Filling draw calls is where the vertex buffers get created and meshes get generated that are later drawn to show your UI. The time it takes for this function to complete depends on the complexity of your UI and the number of widgets within your panels. If you have 1000 widgets all under 1 panel, then it will be much more expensive to perform than say, 1 widget per 1000 panels (although in the latter case you will also have 1000 draw calls -- not acceptable for mobile).
How many widgets do you have per card? You can try having nested panels in there, say one panel per card. Moving panels is very efficient, so you will effectively eliminate all draw call filling altogether.
Title: Re: DrawCall Rebuild Causing Performance Issue
Post by: madturtle84 on August 23, 2016, 10:22:48 AM
Quote
How many widgets do you have per card? You can try having nested panels in there, say one panel per card. Moving panels is very efficient, so you will effectively eliminate all draw call filling altogether.
Thank you ArenMook! The performance is much better now.
Each of my "card" contain 16 widget, so I used to have about 1600 widgets in one panel. After splitting the panel there is no more spike for the FillAllDrawcalls. On my Samsung S3 it runs at around 15 FPS when dragging -- not perfect but acceptable.
By the way, when I was using the "one big panel" method, I noticed the "FillAllDrawcall" function sometime get called even I do nothing. It appear the offscreen widget movement or alpha change also trigger this function. Is it possible to optimize it by checking the isVisible parameter in the "UpdateWidgets()" function? (As shown in the code below at the last line)
Will it have any side effect?
// Copy from UIPanel.UpdateWidgets
if(!mRebuild)
{
// Find an existing draw call, if possible
if(w.drawCall!=null) w.drawCall.isDirty=true;
else FindDrawCall(w);
// ^- Can we change this line to:
// else if(w.isVisible) FindDrawCall(w)
}
Title: Re: DrawCall Rebuild Causing Performance Issue
Post by: ArenMook on August 24, 2016, 02:36:36 PM
There is a "cull" option on the panels you can check, it should already do what you're expecting I believe. Basically off-screen widgets will not be drawn. By default all widgets get added to draw calls, even if they are off-screen. It's intentional.