From 97edbb7f374da3f9a41c39afecaaee627b1fb5db Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 3 Jul 2017 14:43:44 -0700 Subject: [PATCH] Restore mutex in overlay interface --- interface/src/ui/overlays/Overlays.cpp | 98 +++++++++++++++++++------- interface/src/ui/overlays/Overlays.h | 1 + 2 files changed, 74 insertions(+), 25 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 0c73f1fa70..1495bc2d77 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -40,19 +40,23 @@ Q_LOGGING_CATEGORY(trace_render_overlays, "trace.render.overlays") void Overlays::cleanupAllOverlays() { + QMap overlaysHUD; + QMap overlaysWorld; { - foreach(Overlay::Pointer overlay, _overlaysHUD) { - _overlaysToDelete.push_back(overlay); - } - foreach(Overlay::Pointer overlay, _overlaysWorld) { - _overlaysToDelete.push_back(overlay); - } - _overlaysHUD.clear(); - _overlaysWorld.clear(); -#if OVERLAY_PANELS - _panels.clear(); -#endif + QMutexLocker locker(&_mutex); + overlaysHUD.swap(_overlaysHUD); + overlaysWorld.swap(_overlaysWorld); } + + foreach(Overlay::Pointer overlay, overlaysHUD) { + _overlaysToDelete.push_back(overlay); + } + foreach(Overlay::Pointer overlay, overlaysWorld) { + _overlaysToDelete.push_back(overlay); + } +#if OVERLAY_PANELS + _panels.clear(); +#endif cleanupOverlaysToDelete(); } @@ -63,14 +67,19 @@ void Overlays::init() { } void Overlays::update(float deltatime) { - + QMap overlaysHUD; + QMap overlaysWorld; { - foreach(Overlay::Pointer thisOverlay, _overlaysHUD) { - thisOverlay->update(deltatime); - } - foreach(Overlay::Pointer thisOverlay, _overlaysWorld) { - thisOverlay->update(deltatime); - } + QMutexLocker locker(&_mutex); + overlaysHUD = _overlaysHUD; + overlaysWorld = _overlaysWorld; + } + + foreach(const auto& thisOverlay, overlaysHUD) { + thisOverlay->update(deltatime); + } + foreach(const auto& thisOverlay, overlaysWorld) { + thisOverlay->update(deltatime); } cleanupOverlaysToDelete(); @@ -110,8 +119,14 @@ void Overlays::renderHUD(RenderArgs* renderArgs) { int height = size.y; mat4 legacyProjection = glm::ortho(0, width, height, 0, -1000, 1000); + QMap overlaysHUD; + { + QMutexLocker locker(&_mutex); + overlaysHUD = _overlaysHUD; + } - foreach(Overlay::Pointer thisOverlay, _overlaysHUD) { + + foreach(Overlay::Pointer thisOverlay, overlaysHUD) { // Reset all batch pipeline settings between overlay geometryCache->useSimpleDrawPipeline(batch); @@ -132,7 +147,10 @@ void Overlays::enable() { _enabled = true; } +// Note, can't be invoked by scripts, but can be called by the InterfaceParentFinder +// class on packet processing threads Overlay::Pointer Overlays::getOverlay(OverlayID id) const { + QMutexLocker locker(&_mutex); if (_overlaysHUD.contains(id)) { return _overlaysHUD[id]; } @@ -193,13 +211,17 @@ OverlayID Overlays::addOverlay(const Overlay::Pointer& overlay) { overlay->setOverlayID(thisID); overlay->setStackOrder(_stackOrder++); if (overlay->is3D()) { - _overlaysWorld[thisID] = overlay; + { + QMutexLocker locker(&_mutex); + _overlaysWorld[thisID] = overlay; + } render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; overlay->addToScene(overlay, scene, transaction); scene->enqueueTransaction(transaction); } else { + QMutexLocker locker(&_mutex); _overlaysHUD[thisID] = overlay; } @@ -275,6 +297,7 @@ void Overlays::deleteOverlay(OverlayID id) { Overlay::Pointer overlayToDelete; { + QMutexLocker locker(&_mutex); if (_overlaysHUD.contains(id)) { overlayToDelete = _overlaysHUD.take(id); } else if (_overlaysWorld.contains(id)) { @@ -378,7 +401,13 @@ OverlayID Overlays::getOverlayAtPoint(const glm::vec2& point) { if (!_enabled) { return UNKNOWN_OVERLAY_ID; } - QMapIterator i(_overlaysHUD); + + QMap overlaysHUD; + { + QMutexLocker locker(&_mutex); + overlaysHUD = _overlaysHUD; + } + QMapIterator i(overlaysHUD); const float LARGE_NEGATIVE_FLOAT = -9999999; glm::vec3 origin(pointCopy.x, pointCopy.y, LARGE_NEGATIVE_FLOAT); @@ -466,8 +495,14 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionInternal(const PickR float bestDistance = std::numeric_limits::max(); bool bestIsFront = false; + QMap overlaysWorld; + { + QMutexLocker locker(&_mutex); + overlaysWorld = _overlaysWorld; + } + RayToOverlayIntersectionResult result; - QMapIterator i(_overlaysWorld); + QMapIterator i(overlaysWorld); while (i.hasNext()) { i.next(); OverlayID thisID = i.key(); @@ -598,13 +633,20 @@ QSizeF Overlays::textSize(OverlayID id, const QString& text) { return result; } - Overlay::Pointer thisOverlay = _overlaysHUD[id]; + Overlay::Pointer thisOverlay; + { + QMutexLocker locker(&_mutex); + thisOverlay = _overlaysHUD[id]; + } if (thisOverlay) { if (auto textOverlay = std::dynamic_pointer_cast(thisOverlay)) { return textOverlay->textSize(text); } } else { - thisOverlay = _overlaysWorld[id]; + { + QMutexLocker locker(&_mutex); + thisOverlay = _overlaysWorld[id]; + } if (auto text3dOverlay = std::dynamic_pointer_cast(thisOverlay)) { return text3dOverlay->textSize(text); } @@ -675,6 +717,7 @@ bool Overlays::isAddedOverlay(OverlayID id) { return result; } + QMutexLocker locker(&_mutex); return _overlaysHUD.contains(id) || _overlaysWorld.contains(id); } @@ -949,8 +992,13 @@ QVector Overlays::findOverlays(const glm::vec3& center, float radius) { return result; } + QMap overlaysWorld; + { + QMutexLocker locker(&_mutex); + overlaysWorld = _overlaysWorld; + } - QMapIterator i(_overlaysWorld); + QMapIterator i(overlaysWorld); int checked = 0; while (i.hasNext()) { checked++; diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index d3fa70225e..bfb775b041 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -319,6 +319,7 @@ signals: private: void cleanupOverlaysToDelete(); + mutable QMutex _mutex; QMap _overlaysHUD; QMap _overlaysWorld; #if OVERLAY_PANELS