[qt] Add an interface for Static rendering

This commit is contained in:
Thiago Marcos P. Santos
2018-02-06 19:31:06 +02:00
parent 36a0c98713
commit d229cbb031
5 changed files with 123 additions and 5 deletions

View File

@@ -26,6 +26,11 @@ public:
SharedGLContext
};
enum MapMode {
Continuous = 0,
Static
};
enum ConstrainMode {
NoConstrain = 0,
ConstrainHeightOnly,
@@ -40,6 +45,9 @@ public:
GLContextMode contextMode() const;
void setContextMode(GLContextMode);
MapMode mapMode() const;
void setMapMode(MapMode);
ConstrainMode constrainMode() const;
void setConstrainMode(ConstrainMode);
@@ -66,6 +74,7 @@ public:
private:
GLContextMode m_contextMode;
MapMode m_mapMode;
ConstrainMode m_constrainMode;
ViewportMode m_viewportMode;
@@ -235,11 +244,17 @@ public slots:
void render();
void connectionEstablished();
// Commit changes, load all the resources
// and renders the map when completed.
void startStaticRender();
signals:
void needsRendering();
void mapChanged(QMapboxGL::MapChange);
void copyrightsChanged(const QString &copyrightsHtml);
void staticRenderFinished(const QString &error);
private:
Q_DISABLE_COPY(QMapboxGL)

View File

@@ -64,6 +64,10 @@ using namespace QMapbox;
static_assert(mbgl::underlying_type(QMapboxGLSettings::UniqueGLContext) == mbgl::underlying_type(mbgl::GLContextMode::Unique), "error");
static_assert(mbgl::underlying_type(QMapboxGLSettings::SharedGLContext) == mbgl::underlying_type(mbgl::GLContextMode::Shared), "error");
// mbgl::MapMode
static_assert(mbgl::underlying_type(QMapboxGLSettings::Continuous) == mbgl::underlying_type(mbgl::MapMode::Continuous), "error");
static_assert(mbgl::underlying_type(QMapboxGLSettings::Static) == mbgl::underlying_type(mbgl::MapMode::Static), "error");
// mbgl::ConstrainMode
static_assert(mbgl::underlying_type(QMapboxGLSettings::NoConstrain) == mbgl::underlying_type(mbgl::ConstrainMode::None), "error");
static_assert(mbgl::underlying_type(QMapboxGLSettings::ConstrainHeightOnly) == mbgl::underlying_type(mbgl::ConstrainMode::HeightOnly), "error");
@@ -163,6 +167,27 @@ std::unique_ptr<mbgl::style::Image> toStyleImage(const QString &id, const QImage
\sa contextMode()
*/
/*!
\enum QMapboxGLSettings::MapMode
This enum sets the map rendering mode
\value Continuous The map will render as data arrives from the network and
react immediately to state changes.
This is the default mode and the preferred when the map is intended to be
interactive.
\value Static The map will no longer react to state changes and will only
be rendered when QMapboxGL::startStaticRender is called. After all the
resources are loaded, the QMapboxGL::staticRenderFinished signal is emitted.
This mode is useful for taking a snapshot of the finished rendering result
of the map into a QImage.
\sa mapMode()
*/
/*!
\enum QMapboxGLSettings::ConstrainMode
@@ -199,6 +224,7 @@ std::unique_ptr<mbgl::style::Image> toStyleImage(const QString &id, const QImage
*/
QMapboxGLSettings::QMapboxGLSettings()
: m_contextMode(QMapboxGLSettings::SharedGLContext)
, m_mapMode(QMapboxGLSettings::Continuous)
, m_constrainMode(QMapboxGLSettings::ConstrainHeightOnly)
, m_viewportMode(QMapboxGLSettings::DefaultViewport)
, m_cacheMaximumSize(mbgl::util::DEFAULT_MAX_CACHE_SIZE)
@@ -228,6 +254,31 @@ void QMapboxGLSettings::setContextMode(GLContextMode mode)
m_contextMode = mode;
}
/*!
Returns the map mode. Static mode will emit a signal for
rendering a map only when the map is fully loaded.
Animations like style transitions and labels fading won't
be seen.
The Continuous mode will emit the signal for every new
change on the map and it is usually what you expect for
a interactive map.
By default, it is set to QMapboxGLSettings::Continuous.
*/
QMapboxGLSettings::MapMode QMapboxGLSettings::mapMode() const
{
return m_mapMode;
}
/*!
Sets the map \a mode.
*/
void QMapboxGLSettings::setMapMode(MapMode mode)
{
m_mapMode = mode;
}
/*!
Returns the constrain mode. This is used to limit the map to wrap
around the globe horizontally.
@@ -1473,6 +1524,29 @@ void QMapboxGL::destroyRenderer()
d_ptr->destroyRenderer();
}
/*!
Start a static rendering of the current state of the map. This
should only be called when the map is initialized in static mode.
\sa QMapboxGLSettings::MapMode
*/
void QMapboxGL::startStaticRender()
{
d_ptr->mapObj->renderStill([this](std::exception_ptr err) {
QString what;
try {
if (err) {
std::rethrow_exception(err);
}
} catch(const std::exception& e) {
what = e.what();
}
emit staticRenderFinished(what);
});
}
/*!
Renders the map using OpenGL draw calls. It will make sure to bind the
framebuffer object before drawing; otherwise a valid OpenGL context is
@@ -1520,6 +1594,16 @@ void QMapboxGL::connectionEstablished()
\sa render()
*/
/*!
\fn void QMapboxGL::staticRenderFinished(const QString &error)
This signal is emitted when a static map is fully drawn. Usually the next
step is to extract the map from a framebuffer into a container like a
QImage. \a error is set to a message when an error occurs.
\sa startStaticRender()
*/
/*!
\fn void QMapboxGL::mapChanged(QMapboxGL::MapChange change)
@@ -1573,7 +1657,7 @@ QMapboxGLPrivate::QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &settin
*m_mapObserver,
sanitizedSize(size),
m_pixelRatio, *m_fileSourceObj, *m_threadPool,
mbgl::MapMode::Continuous,
static_cast<mbgl::MapMode>(settings.mapMode()),
static_cast<mbgl::ConstrainMode>(settings.constrainMode()),
static_cast<mbgl::ViewportMode>(settings.viewportMode()));
@@ -1595,9 +1679,7 @@ void QMapboxGLPrivate::update(std::shared_ptr<mbgl::UpdateParameters> parameters
m_mapRenderer->updateParameters(std::move(parameters));
if (!m_renderQueued.test_and_set()) {
emit needsRendering();
}
requestRendering();
}
void QMapboxGLPrivate::setObserver(mbgl::RendererObserver &observer)
@@ -1627,6 +1709,8 @@ void QMapboxGLPrivate::createRenderer()
m_mode
);
connect(m_mapRenderer.get(), SIGNAL(needsRendering()), this, SLOT(requestRendering()));
m_mapRenderer->setObserver(m_rendererObserver);
}
@@ -1667,3 +1751,10 @@ void QMapboxGLPrivate::setFramebufferObject(quint32 fbo, const QSize& size)
m_mapRenderer->updateFramebuffer(fbo, sanitizedSize(size));
}
void QMapboxGLPrivate::requestRendering()
{
if (!m_renderQueued.test_and_set()) {
emit needsRendering();
}
}

View File

@@ -18,6 +18,10 @@ 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)

View File

@@ -23,8 +23,10 @@ class UpdateParameters;
class QMapboxGLRendererBackend;
class QMapboxGLMapRenderer : public mbgl::Scheduler
class QMapboxGLMapRenderer : public QObject, public mbgl::Scheduler
{
Q_OBJECT
public:
QMapboxGLMapRenderer(qreal pixelRatio, mbgl::DefaultFileSource &,
mbgl::ThreadPool &, QMapboxGLSettings::GLContextMode);
@@ -40,6 +42,9 @@ public:
// Thread-safe, called by the Frontend
void updateParameters(std::shared_ptr<mbgl::UpdateParameters>);
signals:
void needsRendering();
private:
MBGL_STORE_THREAD(tid)

View File

@@ -40,6 +40,9 @@ public:
mbgl::EdgeInsets margins;
std::unique_ptr<mbgl::Map> mapObj;
public slots:
void requestRendering();
signals:
void needsRendering();