mirror of
https://github.com/overte-org/overte.git
synced 2025-07-26 07:00:09 +02:00
Merge pull request #10925 from jherico/overlay_performance
Fix terrible script performance when rendering load is too high
This commit is contained in:
commit
8043caa9e9
3 changed files with 81 additions and 70 deletions
|
@ -2729,56 +2729,43 @@ bool Application::importSVOFromURL(const QString& urlString) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _renderRequested { false };
|
||||||
|
|
||||||
bool Application::event(QEvent* event) {
|
bool Application::event(QEvent* event) {
|
||||||
if (!Menu::getInstance()) {
|
if (!Menu::getInstance()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Presentation/painting logic
|
int type = event->type();
|
||||||
// TODO: Decouple presentation and painting loops
|
switch (type) {
|
||||||
static bool isPaintingThrottled = false;
|
case Event::Lambda:
|
||||||
if ((int)event->type() == (int)Present) {
|
static_cast<LambdaEvent*>(event)->call();
|
||||||
if (isPaintingThrottled) {
|
|
||||||
// If painting (triggered by presentation) is hogging the main thread,
|
|
||||||
// repost as low priority to avoid hanging the GUI.
|
|
||||||
// This has the effect of allowing presentation to exceed the paint budget by X times and
|
|
||||||
// only dropping every (1/X) frames, instead of every ceil(X) frames
|
|
||||||
// (e.g. at a 60FPS target, painting for 17us would fall to 58.82FPS instead of 30FPS).
|
|
||||||
removePostedEvents(this, Present);
|
|
||||||
postEvent(this, new QEvent(static_cast<QEvent::Type>(Present)), Qt::LowEventPriority);
|
|
||||||
isPaintingThrottled = false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed();
|
case Event::Present:
|
||||||
if (shouldPaint(nsecsElapsed)) {
|
if (!_renderRequested) {
|
||||||
_lastTimeUpdated.start();
|
float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed();
|
||||||
idle(nsecsElapsed);
|
if (shouldPaint(nsecsElapsed)) {
|
||||||
postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority);
|
_renderRequested = true;
|
||||||
}
|
_lastTimeUpdated.start();
|
||||||
isPaintingThrottled = true;
|
idle(nsecsElapsed);
|
||||||
|
postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
return true;
|
case Event::Paint:
|
||||||
} else if ((int)event->type() == (int)Paint) {
|
// NOTE: This must be updated as close to painting as possible,
|
||||||
// NOTE: This must be updated as close to painting as possible,
|
// or AvatarInputs will mysteriously move to the bottom-right
|
||||||
// or AvatarInputs will mysteriously move to the bottom-right
|
AvatarInputs::getInstance()->update();
|
||||||
AvatarInputs::getInstance()->update();
|
paintGL();
|
||||||
|
// wait for the next present event before starting idle / paint again
|
||||||
|
removePostedEvents(this, Present);
|
||||||
|
_renderRequested = false;
|
||||||
|
return true;
|
||||||
|
|
||||||
paintGL();
|
default:
|
||||||
|
break;
|
||||||
isPaintingThrottled = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else if ((int)event->type() == (int)Idle) {
|
|
||||||
float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed();
|
|
||||||
idle(nsecsElapsed);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((int)event->type() == (int)Lambda) {
|
|
||||||
static_cast<LambdaEvent*>(event)->call();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -152,6 +152,7 @@ Overlay::Pointer Overlays::getOverlay(OverlayID id) const {
|
||||||
OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties) {
|
OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
OverlayID result;
|
OverlayID result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
BLOCKING_INVOKE_METHOD(this, "addOverlay", Q_RETURN_ARG(OverlayID, result), Q_ARG(QString, type), Q_ARG(QVariant, properties));
|
BLOCKING_INVOKE_METHOD(this, "addOverlay", Q_RETURN_ARG(OverlayID, result), Q_ARG(QString, type), Q_ARG(QVariant, properties));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -220,6 +221,7 @@ OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) {
|
||||||
OverlayID Overlays::cloneOverlay(OverlayID id) {
|
OverlayID Overlays::cloneOverlay(OverlayID id) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
OverlayID result;
|
OverlayID result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
BLOCKING_INVOKE_METHOD(this, "cloneOverlay", Q_RETURN_ARG(OverlayID, result), Q_ARG(OverlayID, id));
|
BLOCKING_INVOKE_METHOD(this, "cloneOverlay", Q_RETURN_ARG(OverlayID, result), Q_ARG(OverlayID, id));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -315,6 +317,7 @@ void Overlays::deleteOverlay(OverlayID id) {
|
||||||
QString Overlays::getOverlayType(OverlayID overlayId) {
|
QString Overlays::getOverlayType(OverlayID overlayId) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QString result;
|
QString result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
BLOCKING_INVOKE_METHOD(this, "getOverlayType", Q_RETURN_ARG(QString, result), Q_ARG(OverlayID, overlayId));
|
BLOCKING_INVOKE_METHOD(this, "getOverlayType", Q_RETURN_ARG(QString, result), Q_ARG(OverlayID, overlayId));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -329,6 +332,7 @@ QString Overlays::getOverlayType(OverlayID overlayId) {
|
||||||
QObject* Overlays::getOverlayObject(OverlayID id) {
|
QObject* Overlays::getOverlayObject(OverlayID id) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QObject* result;
|
QObject* result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
BLOCKING_INVOKE_METHOD(this, "getOverlayObject", Q_RETURN_ARG(QObject*, result), Q_ARG(OverlayID, id));
|
BLOCKING_INVOKE_METHOD(this, "getOverlayObject", Q_RETURN_ARG(QObject*, result), Q_ARG(OverlayID, id));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -384,12 +388,6 @@ void Overlays::setParentPanel(OverlayID childId, OverlayID panelId) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OverlayID Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
OverlayID Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
||||||
if (QThread::currentThread() != thread()) {
|
|
||||||
OverlayID result;
|
|
||||||
BLOCKING_INVOKE_METHOD(this, "getOverlayAtPoint", Q_RETURN_ARG(OverlayID, result), Q_ARG(glm::vec2, point));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_enabled) {
|
if (!_enabled) {
|
||||||
return UNKNOWN_OVERLAY_ID;
|
return UNKNOWN_OVERLAY_ID;
|
||||||
}
|
}
|
||||||
|
@ -414,20 +412,47 @@ OverlayID Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayPropertyResult Overlays::getProperty(OverlayID id, const QString& property) {
|
OverlayPropertyResult Overlays::getProperty(OverlayID id, const QString& property) {
|
||||||
if (QThread::currentThread() != thread()) {
|
|
||||||
OverlayPropertyResult result;
|
|
||||||
BLOCKING_INVOKE_METHOD(this, "getProperty", Q_RETURN_ARG(OverlayPropertyResult, result), Q_ARG(OverlayID, id), Q_ARG(QString, property));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
OverlayPropertyResult result;
|
|
||||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||||
|
OverlayPropertyResult result;
|
||||||
if (thisOverlay && thisOverlay->supportsGetProperty()) {
|
if (thisOverlay && thisOverlay->supportsGetProperty()) {
|
||||||
result.value = thisOverlay->getProperty(property);
|
result.value = thisOverlay->getProperty(property);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OverlayPropertyResult Overlays::getProperties(const OverlayID& id, const QStringList& properties) {
|
||||||
|
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||||
|
OverlayPropertyResult result;
|
||||||
|
if (thisOverlay && thisOverlay->supportsGetProperty()) {
|
||||||
|
QVariantMap mapResult;
|
||||||
|
for (const auto& property : properties) {
|
||||||
|
mapResult.insert(property, thisOverlay->getProperty(property));
|
||||||
|
}
|
||||||
|
result.value = mapResult;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayPropertyResult Overlays::getOverlaysProperties(const QVariant& propertiesById) {
|
||||||
|
QVariantMap map = propertiesById.toMap();
|
||||||
|
OverlayPropertyResult result;
|
||||||
|
QVariantMap resultMap;
|
||||||
|
for (const auto& key : map.keys()) {
|
||||||
|
OverlayID id = OverlayID(key);
|
||||||
|
QVariantMap overlayResult;
|
||||||
|
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||||
|
if (thisOverlay && thisOverlay->supportsGetProperty()) {
|
||||||
|
QStringList propertiesToFetch = map[key].toStringList();
|
||||||
|
for (const auto& property : propertiesToFetch) {
|
||||||
|
overlayResult[property] = thisOverlay->getProperty(property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultMap[key] = overlayResult;
|
||||||
|
}
|
||||||
|
result.value = resultMap;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
OverlayPropertyResult::OverlayPropertyResult() {
|
OverlayPropertyResult::OverlayPropertyResult() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,18 +484,6 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionInternal(const PickR
|
||||||
const QVector<OverlayID>& overlaysToInclude,
|
const QVector<OverlayID>& overlaysToInclude,
|
||||||
const QVector<OverlayID>& overlaysToDiscard,
|
const QVector<OverlayID>& overlaysToDiscard,
|
||||||
bool visibleOnly, bool collidableOnly) {
|
bool visibleOnly, bool collidableOnly) {
|
||||||
if (QThread::currentThread() != thread()) {
|
|
||||||
RayToOverlayIntersectionResult result;
|
|
||||||
BLOCKING_INVOKE_METHOD(this, "findRayIntersectionInternal", Q_RETURN_ARG(RayToOverlayIntersectionResult, result),
|
|
||||||
Q_ARG(PickRay, ray),
|
|
||||||
Q_ARG(bool, precisionPicking),
|
|
||||||
Q_ARG(QVector<OverlayID>, overlaysToInclude),
|
|
||||||
Q_ARG(QVector<OverlayID>, overlaysToDiscard),
|
|
||||||
Q_ARG(bool, visibleOnly),
|
|
||||||
Q_ARG(bool, collidableOnly));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
float bestDistance = std::numeric_limits<float>::max();
|
float bestDistance = std::numeric_limits<float>::max();
|
||||||
bool bestIsFront = false;
|
bool bestIsFront = false;
|
||||||
|
|
||||||
|
@ -589,6 +602,7 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& objectVar
|
||||||
bool Overlays::isLoaded(OverlayID id) {
|
bool Overlays::isLoaded(OverlayID id) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
bool result;
|
bool result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
BLOCKING_INVOKE_METHOD(this, "isLoaded", Q_RETURN_ARG(bool, result), Q_ARG(OverlayID, id));
|
BLOCKING_INVOKE_METHOD(this, "isLoaded", Q_RETURN_ARG(bool, result), Q_ARG(OverlayID, id));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -603,6 +617,7 @@ bool Overlays::isLoaded(OverlayID id) {
|
||||||
QSizeF Overlays::textSize(OverlayID id, const QString& text) {
|
QSizeF Overlays::textSize(OverlayID id, const QString& text) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QSizeF result;
|
QSizeF result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
BLOCKING_INVOKE_METHOD(this, "textSize", Q_RETURN_ARG(QSizeF, result), Q_ARG(OverlayID, id), Q_ARG(QString, text));
|
BLOCKING_INVOKE_METHOD(this, "textSize", Q_RETURN_ARG(QSizeF, result), Q_ARG(OverlayID, id), Q_ARG(QString, text));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -681,6 +696,7 @@ void Overlays::deletePanel(OverlayID panelId) {
|
||||||
bool Overlays::isAddedOverlay(OverlayID id) {
|
bool Overlays::isAddedOverlay(OverlayID id) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
bool result;
|
bool result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
BLOCKING_INVOKE_METHOD(this, "isAddedOverlay", Q_RETURN_ARG(bool, result), Q_ARG(OverlayID, id));
|
BLOCKING_INVOKE_METHOD(this, "isAddedOverlay", Q_RETURN_ARG(bool, result), Q_ARG(OverlayID, id));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -716,6 +732,7 @@ void Overlays::sendHoverLeaveOverlay(OverlayID id, PointerEvent event) {
|
||||||
OverlayID Overlays::getKeyboardFocusOverlay() {
|
OverlayID Overlays::getKeyboardFocusOverlay() {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
OverlayID result;
|
OverlayID result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
BLOCKING_INVOKE_METHOD(this, "getKeyboardFocusOverlay", Q_RETURN_ARG(OverlayID, result));
|
BLOCKING_INVOKE_METHOD(this, "getKeyboardFocusOverlay", Q_RETURN_ARG(OverlayID, result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -735,6 +752,7 @@ void Overlays::setKeyboardFocusOverlay(OverlayID id) {
|
||||||
float Overlays::width() {
|
float Overlays::width() {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
float result;
|
float result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
BLOCKING_INVOKE_METHOD(this, "width", Q_RETURN_ARG(float, result));
|
BLOCKING_INVOKE_METHOD(this, "width", Q_RETURN_ARG(float, result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -746,6 +764,7 @@ float Overlays::width() {
|
||||||
float Overlays::height() {
|
float Overlays::height() {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
float result;
|
float result;
|
||||||
|
PROFILE_RANGE(script, __FUNCTION__);
|
||||||
BLOCKING_INVOKE_METHOD(this, "height", Q_RETURN_ARG(float, result));
|
BLOCKING_INVOKE_METHOD(this, "height", Q_RETURN_ARG(float, result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -955,10 +974,11 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) {
|
||||||
|
|
||||||
QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
||||||
QVector<QUuid> result;
|
QVector<QUuid> result;
|
||||||
if (QThread::currentThread() != thread()) {
|
//if (QThread::currentThread() != thread()) {
|
||||||
BLOCKING_INVOKE_METHOD(this, "findOverlays", Q_RETURN_ARG(QVector<QUuid>, result), Q_ARG(glm::vec3, center), Q_ARG(float, radius));
|
// PROFILE_RANGE(script, __FUNCTION__);
|
||||||
return result;
|
// BLOCKING_INVOKE_METHOD(this, "findOverlays", Q_RETURN_ARG(QVector<QUuid>, result), Q_ARG(glm::vec3, center), Q_ARG(float, radius));
|
||||||
}
|
// return result;
|
||||||
|
//}
|
||||||
|
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
QMapIterator<OverlayID, Overlay::Pointer> i(_overlaysWorld);
|
QMapIterator<OverlayID, Overlay::Pointer> i(_overlaysWorld);
|
||||||
|
|
|
@ -190,6 +190,10 @@ public slots:
|
||||||
*/
|
*/
|
||||||
OverlayPropertyResult getProperty(OverlayID id, const QString& property);
|
OverlayPropertyResult getProperty(OverlayID id, const QString& property);
|
||||||
|
|
||||||
|
OverlayPropertyResult getProperties(const OverlayID& id, const QStringList& properties);
|
||||||
|
|
||||||
|
OverlayPropertyResult getOverlaysProperties(const QVariant& overlaysProperties);
|
||||||
|
|
||||||
/*jsdoc
|
/*jsdoc
|
||||||
* Find the closest 3D overlay hit by a pick ray.
|
* Find the closest 3D overlay hit by a pick ray.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue