Fix terrible script performance when rendering load is too high
Showing the changes to interface/src/Application.cpp (1 of 3 files). Show all
Unified · Split
| @@ -2729,56 +2729,43 @@ bool Application::importSVOFromURL(const QString& urlString) { · 2728 unmodified lines | |||
| 2729 | return true; | 2729 | return true; |
| 2730 | } | 2730 | } |
| 2731 | 2731 | ||
| 2732 | bool _renderRequested { false }; | ||
| 2733 | |||
| 2732 | bool Application::event(QEvent* event) { | 2734 | bool Application::event(QEvent* event) { |
| 2733 | if (!Menu::getInstance()) { | 2735 | if (!Menu::getInstance()) { |
| 2734 | return false; | 2736 | return false; |
| 2735 | } | 2737 | } |
| 2736 | 2738 | ||
| 2737 | // Presentation/painting logic | 2739 | int type = event->type(); |
| 2738 | // TODO: Decouple presentation and painting loops | 2740 | switch (type) { |
| 2739 | static bool isPaintingThrottled = false; | 2741 | case Event::Lambda: |
| 2740 | if ((int)event->type() == (int)Present) { | 2742 | static_cast<LambdaEvent*>(event)->call(); |
| 2741 | if (isPaintingThrottled) { | ||
| 2742 | // If painting (triggered by presentation) is hogging the main thread, | ||
| 2743 | // repost as low priority to avoid hanging the GUI. | ||
| 2744 | // This has the effect of allowing presentation to exceed the paint budget by X times and | ||
| 2745 | // only dropping every (1/X) frames, instead of every ceil(X) frames | ||
| 2746 | // (e.g. at a 60FPS target, painting for 17us would fall to 58.82FPS instead of 30FPS). | ||
| 2747 | removePostedEvents(this, Present); | ||
| 2748 | postEvent(this, new QEvent(static_cast<QEvent::Type>(Present)), Qt::LowEventPriority); | ||
| 2749 | isPaintingThrottled = false; | ||
| 2750 | return true; | 2743 | return true; |
| 2751 | } | ||
| 2752 | |||
| 2753 | float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed(); | ||
| 2754 | if (shouldPaint(nsecsElapsed)) { | ||
| 2755 | _lastTimeUpdated.start(); | ||
| 2756 | idle(nsecsElapsed); | ||
| 2757 | postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority); | ||
| 2758 | } | ||
| 2759 | isPaintingThrottled = true; | ||
| 2760 | 2744 | ||
| 2761 | return true; | 2745 | case Event::Present: |
| 2762 | } else if ((int)event->type() == (int)Paint) { | 2746 | if (!_renderRequested) { |
| 2763 | // NOTE: This must be updated as close to painting as possible, | 2747 | float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed(); |
| 2764 | // or AvatarInputs will mysteriously move to the bottom-right | 2748 | if (shouldPaint(nsecsElapsed)) { |
| 2765 | AvatarInputs::getInstance()->update(); | 2749 | _renderRequested = true; |
| 2766 | 2750 | _lastTimeUpdated.start(); | |
| 2767 | paintGL(); | 2751 | idle(nsecsElapsed); |
| 2768 | 2752 | postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority); | |
| 2769 | isPaintingThrottled = false; | 2753 | } |
| 2770 | 2754 | } | |
| 2771 | return true; | 2755 | return true; |
| 2772 | } else if ((int)event->type() == (int)Idle) { | ||
| 2773 | float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed(); | ||
| 2774 | idle(nsecsElapsed); | ||
| 2775 | 2756 | ||
| 2776 | return true; | 2757 | case Event::Paint: |
| 2777 | } | 2758 | // NOTE: This must be updated as close to painting as possible, |
| 2759 | // or AvatarInputs will mysteriously move to the bottom-right | ||
| 2760 | AvatarInputs::getInstance()->update(); | ||
| 2761 | paintGL(); | ||
| 2762 | // wait for the next present event before starting idle / paint again | ||
| 2763 | removePostedEvents(this, Present); | ||
| 2764 | _renderRequested = false; | ||
| 2765 | return true; | ||
| 2778 | 2766 | ||
| 2779 | if ((int)event->type() == (int)Lambda) { | 2767 | default: |
| 2780 | static_cast<LambdaEvent*>(event)->call(); | 2768 | break; |
| 2781 | return true; | ||
| 2782 | } | 2769 | } |
| 2783 | 2770 | ||
| 2784 | { | 2771 | { |