You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Editor/Core
Chris Burel d2cdb511d0
Improve the framerate of Editor widgets that update in the TickBus (#7408)
Previously, with no level loaded in the main editor, and no assets loaded
in the EMotionFX editor, the AnimGraph viewport would only update at 15fps,
even on a 64 core machine.

Digging into this with Pix, I found that EMotionFX's UI would only get
updated for every other call to the ComponentApplication tick.

The Editor's QApplication instance controls how the
`ComponentApplication::OnTick` method is called. This is done in the
`maybeProcessIdle()` method. Generally, I found callstacks like this:

```
EditorQtApplication::maybeProcessIdle()
  CCryEditApp::OnIdle()
    CCryEditApp::IdleProcessing()
      CGameEngine::Update()                  # ~2.2ms
        PhysX::Update()                      # ~1.8ms
        EMotionFX::Update()                  # ~0.2ms
          calls QWidget::update() on all the widgets that change per
          frame, only puts update events on the event queue, doesn't
          paint anything
      AZ::ComponentApplication::TickSystem() # ~25ms
        renders the frame with Atom          # ~24ms
```

The `maybeProcessIdle()` method is invoked by a QTimer, with a timeout
that changes depending on the application state. If the Editor is in
game mode, it used a timeout of 0, which essentially forced the game to
run at as high an fps as possible. If the Editor application has focus,
it used a timeout of 1ms, asking for the idle processing to happen at
1000 fps.  Otherwise, it used a timeout of 10ms, asking for idle
processing at 100 fps.

Those fps targets are not realistic. What happened in this case is that
while the PhysX system was being updated, while the previous
`maybeProcessIdle()` call was still processing, the idle processing
timer would timeout again, and place a timer event on Qt's event queue,
before anything else had a chance to do anything. Only afterward would
EMotionFX's MainWindow::OnTick would be invoked, placing paint events on
Qt's event queue.

The fix for this is to use a single shot timer at the end of each
`maybeProcessIdle()` call. This ensures that any events that are
enqueued during the `maybeProcessIdle()` call are processed prior to the
next call to `maybeProcessIdle()`.

Signed-off-by: Chris Burel <burelc@amazon.com>
4 years ago
..
Tests Update the FileIO Aliases (#4186) 4 years ago
EditorMetricsPlainTextNameRegistration.cpp Shorten copyright headers by splitting into 2 lines (#2213) 4 years ago
EditorMetricsPlainTextNameRegistration.h Shorten copyright headers by splitting into 2 lines (#2213) 4 years ago
LevelEditorMenuHandler.cpp Deprecate IsPrefabSystemForLevelsEnabled and use IsPrefabSystemEnabled everywhere (#7327) 4 years ago
LevelEditorMenuHandler.h Remove redundant editor mode notifications. 4 years ago
QtEditorApplication.cpp Improve the framerate of Editor widgets that update in the TickBus (#7408) 4 years ago
QtEditorApplication.h Improve the framerate of Editor widgets that update in the TickBus (#7408) 4 years ago