Author Topic: DrawCall Rebuild Causing Performance Issue  (Read 4532 times)

madturtle84

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 2
    • View Profile
DrawCall Rebuild Causing Performance Issue
« 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 :


Is there anything I can do to improve the performance?
« Last Edit: August 19, 2016, 04:56:51 PM by madturtle84 »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: DrawCall Rebuild Causing Performance Issue
« Reply #1 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.

madturtle84

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 2
    • View Profile
Re: DrawCall Rebuild Causing Performance Issue
« Reply #2 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?

  1. // Copy from UIPanel.UpdateWidgets
  2.  
  3.    if (!mRebuild)
  4.    {
  5.       // Find an existing draw call, if possible
  6.       if (w.drawCall != null) w.drawCall.isDirty = true;
  7.       else FindDrawCall(w);
  8.       // ^- Can we change this line to:
  9.       // else if(w.isVisible) FindDrawCall(w)
  10.    }
  11.  
  12.  
« Last Edit: August 23, 2016, 09:26:19 PM by madturtle84 »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: DrawCall Rebuild Causing Performance Issue
« Reply #3 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.