diff options
-rw-r--r-- | platform/qt/qt.cmake | 4 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl_map_renderer.cpp | 67 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl_map_renderer.hpp | 11 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl_scheduler.cpp | 36 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl_scheduler.hpp | 31 |
5 files changed, 110 insertions, 39 deletions
diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake index 989618a59a..dda15174fb 100644 --- a/platform/qt/qt.cmake +++ b/platform/qt/qt.cmake @@ -65,8 +65,10 @@ add_library(qmapboxgl SHARED platform/qt/src/qmapboxgl_map_observer.hpp platform/qt/src/qmapboxgl_map_renderer.cpp platform/qt/src/qmapboxgl_map_renderer.hpp - platform/qt/src/qmapboxgl_renderer_backend.hpp platform/qt/src/qmapboxgl_renderer_backend.cpp + platform/qt/src/qmapboxgl_renderer_backend.hpp + platform/qt/src/qmapboxgl_scheduler.cpp + platform/qt/src/qmapboxgl_scheduler.hpp platform/default/mbgl/util/default_styles.hpp ) diff --git a/platform/qt/src/qmapboxgl_map_renderer.cpp b/platform/qt/src/qmapboxgl_map_renderer.cpp index 7a9d1f6f78..acc4194498 100644 --- a/platform/qt/src/qmapboxgl_map_renderer.cpp +++ b/platform/qt/src/qmapboxgl_map_renderer.cpp @@ -1,12 +1,47 @@ #include "qmapboxgl_map_renderer.hpp" +#include "qmapboxgl_scheduler.hpp" +#include <QThreadStorage> #include <QtGlobal> +static bool needsToForceScheduler() { + static QThreadStorage<bool> force; + + if (!force.hasLocalData()) { + force.setLocalData(mbgl::Scheduler::GetCurrent() == nullptr); + } + + return force.localData(); +}; + +static auto *getScheduler() { + static QThreadStorage<std::shared_ptr<QMapboxGLScheduler>> scheduler; + + if (!scheduler.hasLocalData()) { + scheduler.setLocalData(std::make_shared<QMapboxGLScheduler>()); + } + + return scheduler.localData().get(); +}; + QMapboxGLMapRenderer::QMapboxGLMapRenderer(qreal pixelRatio, mbgl::DefaultFileSource &fs, mbgl::ThreadPool &tp, QMapboxGLSettings::GLContextMode mode) : m_renderer(std::make_unique<mbgl::Renderer>(m_backend, pixelRatio, fs, tp, static_cast<mbgl::GLContextMode>(mode))) - , m_threadWithScheduler(Scheduler::GetCurrent() != nullptr) + , m_forceScheduler(needsToForceScheduler()) { + // If we don't have a Scheduler on this thread, which + // is usually the case for render threads, use a shared + // dummy scheduler that needs to be explicitly forced to + // process events. + if (m_forceScheduler) { + auto scheduler = getScheduler(); + + if (mbgl::Scheduler::GetCurrent() == nullptr) { + mbgl::Scheduler::SetCurrent(scheduler); + } + + connect(scheduler, SIGNAL(needsProcessing()), this, SIGNAL(needsRendering())); + } } QMapboxGLMapRenderer::~QMapboxGLMapRenderer() @@ -14,16 +49,6 @@ QMapboxGLMapRenderer::~QMapboxGLMapRenderer() MBGL_VERIFY_THREAD(tid); } -void QMapboxGLMapRenderer::schedule(std::weak_ptr<mbgl::Mailbox> mailbox) -{ - std::lock_guard<std::mutex> lock(m_taskQueueMutex); - m_taskQueue.push(mailbox); - - // Need to force the main thread to wake - // up this thread and process the events. - emit needsRendering(); -} - void QMapboxGLMapRenderer::updateParameters(std::shared_ptr<mbgl::UpdateParameters> newParameters) { std::lock_guard<std::mutex> lock(m_updateMutex); @@ -57,26 +82,10 @@ void QMapboxGLMapRenderer::render() // The OpenGL implementation automatically enables the OpenGL context for us. mbgl::BackendScope scope(m_backend, mbgl::BackendScope::ScopeType::Implicit); - // If we don't have a Scheduler on this thread, which - // is usually the case for render threads, use this - // object as scheduler. - if (!m_threadWithScheduler) { - Scheduler::SetCurrent(this); - } - m_renderer->render(*params); - if (!m_threadWithScheduler) { - std::queue<std::weak_ptr<mbgl::Mailbox>> taskQueue; - { - std::unique_lock<std::mutex> lock(m_taskQueueMutex); - std::swap(taskQueue, m_taskQueue); - } - - while (!taskQueue.empty()) { - mbgl::Mailbox::maybeReceive(taskQueue.front()); - taskQueue.pop(); - } + if (m_forceScheduler) { + getScheduler()->processEvents(); } } diff --git a/platform/qt/src/qmapboxgl_map_renderer.hpp b/platform/qt/src/qmapboxgl_map_renderer.hpp index adba11de51..0b17542e2f 100644 --- a/platform/qt/src/qmapboxgl_map_renderer.hpp +++ b/platform/qt/src/qmapboxgl_map_renderer.hpp @@ -14,7 +14,6 @@ #include <memory> #include <mutex> -#include <queue> namespace mbgl { class Renderer; @@ -23,7 +22,7 @@ class UpdateParameters; class QMapboxGLRendererBackend; -class QMapboxGLMapRenderer : public QObject, public mbgl::Scheduler +class QMapboxGLMapRenderer : public QObject { Q_OBJECT @@ -32,9 +31,6 @@ public: mbgl::ThreadPool &, QMapboxGLSettings::GLContextMode); virtual ~QMapboxGLMapRenderer(); - // mbgl::Scheduler implementation. - void schedule(std::weak_ptr<mbgl::Mailbox> scheduled) final; - void render(); void updateFramebuffer(quint32 fbo, const mbgl::Size &size); void setObserver(std::shared_ptr<mbgl::RendererObserver>); @@ -56,8 +52,5 @@ private: QMapboxGLRendererBackend m_backend; std::unique_ptr<mbgl::Renderer> m_renderer; - std::mutex m_taskQueueMutex; - std::queue<std::weak_ptr<mbgl::Mailbox>> m_taskQueue; - - bool m_threadWithScheduler; + bool m_forceScheduler; }; diff --git a/platform/qt/src/qmapboxgl_scheduler.cpp b/platform/qt/src/qmapboxgl_scheduler.cpp new file mode 100644 index 0000000000..7c64336d5b --- /dev/null +++ b/platform/qt/src/qmapboxgl_scheduler.cpp @@ -0,0 +1,36 @@ +#include "qmapboxgl_scheduler.hpp" + +#include <mbgl/util/util.hpp> + +QMapboxGLScheduler::QMapboxGLScheduler() +{ +} + +QMapboxGLScheduler::~QMapboxGLScheduler() +{ + MBGL_VERIFY_THREAD(tid); +} + +void QMapboxGLScheduler::schedule(std::weak_ptr<mbgl::Mailbox> mailbox) +{ + std::lock_guard<std::mutex> lock(m_taskQueueMutex); + m_taskQueue.push(mailbox); + + // Need to force the main thread to wake + // up this thread and process the events. + emit needsProcessing(); +} + +void QMapboxGLScheduler::processEvents() +{ + std::queue<std::weak_ptr<mbgl::Mailbox>> taskQueue; + { + std::unique_lock<std::mutex> lock(m_taskQueueMutex); + std::swap(taskQueue, m_taskQueue); + } + + while (!taskQueue.empty()) { + mbgl::Mailbox::maybeReceive(taskQueue.front()); + taskQueue.pop(); + } +} diff --git a/platform/qt/src/qmapboxgl_scheduler.hpp b/platform/qt/src/qmapboxgl_scheduler.hpp new file mode 100644 index 0000000000..c23abf816d --- /dev/null +++ b/platform/qt/src/qmapboxgl_scheduler.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include <mbgl/actor/mailbox.hpp> +#include <mbgl/actor/scheduler.hpp> + +#include <QObject> + +#include <memory> +#include <mutex> +#include <queue> + +class QMapboxGLScheduler : public QObject, public mbgl::Scheduler +{ + Q_OBJECT + +public: + QMapboxGLScheduler(); + virtual ~QMapboxGLScheduler(); + + // mbgl::Scheduler implementation. + void schedule(std::weak_ptr<mbgl::Mailbox> scheduled) final; + + void processEvents(); + +signals: + void needsProcessing(); + +private: + std::mutex m_taskQueueMutex; + std::queue<std::weak_ptr<mbgl::Mailbox>> m_taskQueue; +}; |