Progress bar 6ms update?

I have a progress bar:
6101823--663639--upload_2020-7-17_18-4-7.png

<UXML xmlns:ui="UnityEngine.UIElements">
  <ui:VisualElement class="unity-progress-bar__background">
    <ui:VisualElement class="unity-progress-bar__progress" />
    <ui:VisualElement class="unity-progress-bar__title-container">
      <ui:Label text="Preview (Drag)" class="unity-text-element unity-label unity-progress-bar__title" />
    </ui:VisualElement>
  </ui:VisualElement>
</UXML>

When a related object is animating I update this on Editor.Update. Profiling editor reveals:

Set Display to None for just the progress bar element via the UI TK Debugger:


Set Display back to Flex:
Just toggling this progress bar seems to add an additional 6ms and involve a surprising amount of UIR.ImmediateRenderer and gc?.. I even tried setting the usage hint (although I guess this should be set on the moving element within the progress bar anyway):

Is there anything obviously wrong I might be doing here or is it simply that the progress bar is using some old very inefficient code?
I guess I could add a resizing element or custom updating mesh instead but it would be nice if doing this wasn’t brutal :slight_smile:
Many thanks in advance for any help or pointers where I might be going wrong.

ProgressBar isn’t implemented with ImmediateRenderers (which by the way means that rendering isn’t performed by UIT but rather with GL or IMGUI), so you’re probably capturing other stuff in the profiler.

Regarding the usage hints, they must be used cautiously. Don’t set the DynamicTransform usage hint unless the transform of the element is actually being modified frequently. Otherwise you’ll degrade performance.

Thanks for replying @AlexandreT-unity - I’ve created a super minimal repro:

using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;

[CustomEditor(typeof(TestMonoBehaviour))]
public class UITKInspector : Editor
{
    ProgressBar progressBar;
    public override VisualElement CreateInspectorGUI()
    {
        EditorApplication.update += UpdateProgressBar;
        progressBar = new ProgressBar();
        return progressBar;
    }
    private void UpdateProgressBar()
    {
        // Comment in this line to add 2ms editor overhead
        //progressBar.value = (1f + Mathf.Sin((float)EditorApplication.timeSinceStartup)) * 50f;
        EditorApplication.QueuePlayerLoopUpdate();
    }
    void OnDestroy()
    {
        EditorApplication.update -= UpdateProgressBar;
    }
}

Commenting in that line you should see:


Hopefully this isn’t expected behaviour?

I’m aware DynamicTransform usage hint should be used conservatively - are you implying an updating progress bar such as this is a poor use-case?

Many thanks for your help.

(Unity 2020.1.0b10)

I tested your code and what you see is the cost of rendering the whole inspector, and unfortunately most of it is not UIToolkit yet so it’s much slower. So when you modify the progress bar, you force the whole inspector window to repaint, and that includes IMGUI code of other components. If you hover quickly over many items of the inspector, you will observe a similar slowness in the profiler. As time passes, more and more components will use UIToolkit and this should help in that regard.

Regarding DynamicTransform, when the progress bar is updated, its transform isn’t modified so it’s not a good use case. Only the width of the inner progress element is modified, which is different from the transform (not a scaling).

1 Like

Thanks for taking a look. The width adjustment not being the same as scale makes a lot of sense. Does that mean no matter how I update something in the inspector (i.e. using VisualElements instead) that cost will be there until UIT is the default for inspectors? I currently don’t use any non-UIT elements and I have to run QueuePlayerLoopUpdate for updating the scene view etc. If so, any update / rough eta possible on when that default might be coming?
Thanks again.

Yes

Custom inspectors will remain rendered with IMGUI until their owners convert them to UIT. There is no ETA at the moment. Default inspectors will use UI Toolkit most likely sometime next year.

1 Like

Apologies - last clarification I hope. “Custom inspectors will remain rendered with IMGUI until their owners convert them” - who are the owners in this context? Am I not the owner of the above example custom inspector? Or are you referring to the team that owns the concept of custom inspectors?
Just wanting to be sure I haven’t missed some simple concept like I should be extending from something other than Editor?
If I replaced all contents of the editor with components that didn’t use gl/imgui would this help? In which case is there a way to find out which are safe ‘pure UIT’ components?
Thanks for your continued help.

There are multiples team inside unity with their own area of expertise, hence owner. Because of this, each team handle the switch form IMGUI to UITK at their own pace. Each small change will reduce the overall cost of a redraw as we can cache a lot of information in UITK.

Just an idea: In your application, can you reduce the frequency at which you update the progress bar? A Lot of application can have a progress bar refreshed twice per second. This would reduce the overhead.

Thanks @SimonDufour - I can certainly reduce the update frequency but hopefully this gif illustrates the responsive ux I’m striving for. If this really is costing up to 6ms in practice as it seems to be and there’s nothing I can do about it, I likely will have to reduce update, remove the feature or explore some more hacky ideas (floating editor window?) so any other ideas are welcome.

6117674--666479--GIF 22-07-2020 15-27-13.gif

I see how you want the progress bar to match the input of the user! It is definitely different from a progress bar used to indicate a long operation’s progress.

To keep latency to a minimum, I think you should let your code as is when the user moves the mouse: it will render as fast as possible up to the maximum framerate that the computer will allow. As long as you keep 60fps, Only people on a laptop (like me) will notice because of the fan noise. And with 6ms you are closer to 160fps.

By doing that, the performance will naturally increase with the next version of unity.

Do keep in mind that the profiler does reduce the performance a little, especially in deep profile (I have seen up to 40%). So test the look and feel without it also as it is more representative on what your user will do.

Thanks Simon. No need for me to be using a progress bar - just convenient. I could easily replace this with a couple of VisualElements though my understanding is that the cost would be effectively the same regardless.
To be clear the 6ms is ‘extra’ just from the progress bar and does not include the timeline, scene & game views updating so I’m actually closer to 30fps. That’s why it’s frustrating. I haven’t had a chance to test this yet but is the issue that one component redrawing within an inspector tab dirties the entire tab and hence redraws all the other components and inspectors? (that would explain the difference between my minimal repro and realistic numbers)
Edit: On re-reading I realise that is indeed what Alexandre was saying: “…you force the whole inspector window to repaint, and that includes IMGUI code of other components”