summaryrefslogtreecommitdiff
path: root/platform/qt
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2016-10-10 17:16:37 +0200
committerKonstantin Käfer <mail@kkaefer.com>2016-10-25 13:52:36 -0700
commita4d259c33f9bb890bba97fd89552720e3e0ec09b (patch)
tree342ecc27a6993c48f3a2e1d739fce890350bc44d /platform/qt
parent5cc390d694fc7510d445310d8eb9e32429a5e67b (diff)
downloadqtlocation-mapboxgl-a4d259c33f9bb890bba97fd89552720e3e0ec09b.tar.gz
[core] move gl::Context to Backend and refactor View
Diffstat (limited to 'platform/qt')
-rw-r--r--platform/qt/app/mapwindow.cpp26
-rw-r--r--platform/qt/app/mapwindow.hpp2
-rw-r--r--platform/qt/config.cmake3
-rw-r--r--platform/qt/include/qmapboxgl.hpp13
-rw-r--r--platform/qt/src/qmapboxgl.cpp84
-rw-r--r--platform/qt/src/qmapboxgl_p.hpp13
-rw-r--r--platform/qt/src/qquickmapboxglrenderer.cpp12
-rw-r--r--platform/qt/src/qquickmapboxglrenderer.hpp1
-rw-r--r--platform/qt/test/headless_view_qt.cpp82
-rw-r--r--platform/qt/test/qmapboxgl.cpp2
10 files changed, 104 insertions, 134 deletions
diff --git a/platform/qt/app/mapwindow.cpp b/platform/qt/app/mapwindow.cpp
index 0cce6caaed..e8e3a13489 100644
--- a/platform/qt/app/mapwindow.cpp
+++ b/platform/qt/app/mapwindow.cpp
@@ -9,10 +9,15 @@
#include <QMouseEvent>
#include <QString>
+#if QT_VERSION >= 0x050000
+#include <QWindow>
+#endif
+
int kAnimationDuration = 10000;
+
MapWindow::MapWindow(const QMapboxGLSettings &settings)
- : m_map(nullptr, settings)
+ : m_map(nullptr, settings, size(), pixelRatio())
, m_bearingAnimation(&m_map, "bearing")
, m_zoomAnimation(&m_map, "zoom")
{
@@ -46,6 +51,17 @@ void MapWindow::selfTest()
m_zoomAnimation.start();
}
+qreal MapWindow::pixelRatio() {
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
+ return devicePixelRatioF();
+#elif (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+ return devicePixelRatio();
+#else
+ return 1;
+#endif
+}
+
+
void MapWindow::animationFinished()
{
qDebug() << "Animation ticks/s: " << m_animationTicks / static_cast<float>(kAnimationDuration) * 1000.;
@@ -288,16 +304,12 @@ void MapWindow::initializeGL()
QMapbox::initializeGLExtensions();
}
-void MapWindow::resizeGL(int w, int h)
-{
- QSize size(w, h);
- m_map.resize(size);
-}
-
void MapWindow::paintGL()
{
m_frameDraws++;
+ m_map.resize(size(), size() * pixelRatio());
+
#if QT_VERSION < 0x050400 && defined(__APPLE__)
// XXX GL framebuffer is valid only after first attempt of painting on
// older versions of Qt on macOS.
diff --git a/platform/qt/app/mapwindow.hpp b/platform/qt/app/mapwindow.hpp
index fa1c3f4b3b..a579a5bcc5 100644
--- a/platform/qt/app/mapwindow.hpp
+++ b/platform/qt/app/mapwindow.hpp
@@ -24,6 +24,7 @@ protected slots:
private:
void changeStyle();
+ qreal pixelRatio();
// QGLWidget implementation.
void keyPressEvent(QKeyEvent *ev) final;
@@ -32,7 +33,6 @@ private:
void wheelEvent(QWheelEvent *ev) final;
void initializeGL() final;
- void resizeGL(int w, int h) final;
void paintGL() final;
QPointF m_lastPos;
diff --git a/platform/qt/config.cmake b/platform/qt/config.cmake
index 6df311f885..ff86a0dee1 100644
--- a/platform/qt/config.cmake
+++ b/platform/qt/config.cmake
@@ -44,11 +44,10 @@ macro(mbgl_platform_test)
target_sources(mbgl-test
PRIVATE test/src/main.cpp
PRIVATE platform/qt/test/headless_backend_qt.cpp
- PRIVATE platform/qt/test/headless_view_qt.cpp
PRIVATE platform/qt/test/qmapboxgl.cpp
PRIVATE platform/default/headless_backend.cpp
PRIVATE platform/default/headless_display.cpp
- PRIVATE platform/default/headless_view.cpp
+ PRIVATE platform/default/offscreen_view.cpp
)
set_source_files_properties(
diff --git a/platform/qt/include/qmapboxgl.hpp b/platform/qt/include/qmapboxgl.hpp
index ba5631e1e4..d3937ce083 100644
--- a/platform/qt/include/qmapboxgl.hpp
+++ b/platform/qt/include/qmapboxgl.hpp
@@ -3,6 +3,7 @@
#include <QMapbox>
#include <QObject>
+#include <QSize>
#include <QPointF>
class QImage;
@@ -10,6 +11,7 @@ class QMargins;
class QSize;
class QString;
class QStringList;
+class QOpenGLFramebufferObject;
class QMapboxGLPrivate;
@@ -95,7 +97,10 @@ public:
NorthLeftwards,
};
- QMapboxGL(QObject *parent = 0, const QMapboxGLSettings& = QMapboxGLSettings());
+ QMapboxGL(QObject* parent = 0,
+ const QMapboxGLSettings& = QMapboxGLSettings(),
+ const QSize& size = QSize(),
+ qreal pixelRatio = 1);
virtual ~QMapboxGL();
void cycleDebugOptions();
@@ -167,7 +172,7 @@ public:
void scaleBy(double scale, const QPointF &center = QPointF());
void rotateBy(const QPointF &first, const QPointF &second);
- void resize(const QSize &size);
+ void resize(const QSize &size, const QSize &framebufferSize);
void addAnnotationIcon(const QString &name, const QImage &sprite);
@@ -198,7 +203,11 @@ public:
void setFilter(const QString &layer, const QVariant &filter);
public slots:
+#if QT_VERSION >= 0x050000
+ void render(QOpenGLFramebufferObject *fbo = NULL);
+#else
void render();
+#endif
void connectionEstablished();
signals:
diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp
index 73a1771908..edda1f9599 100644
--- a/platform/qt/src/qmapboxgl.cpp
+++ b/platform/qt/src/qmapboxgl.cpp
@@ -6,6 +6,7 @@
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/context.hpp>
#include <mbgl/map/camera.hpp>
#include <mbgl/map/map.hpp>
#include <mbgl/style/conversion.hpp>
@@ -23,6 +24,7 @@
#if QT_VERSION >= 0x050000
#include <QGuiApplication>
#include <QWindow>
+#include <QOpenGLFramebufferObject>
#else
#include <QCoreApplication>
#endif
@@ -271,7 +273,7 @@ void QMapboxGLSettings::setAccessToken(const QString &token)
Constructs a QMapboxGL object with \a settings and sets \a parent as the parent
object. The \a settings cannot be changed after the object is constructed.
*/
-QMapboxGL::QMapboxGL(QObject *parent, const QMapboxGLSettings &settings)
+QMapboxGL::QMapboxGL(QObject *parent, const QMapboxGLSettings &settings, const QSize& size, qreal pixelRatio)
: QObject(parent)
{
// Multiple QMapboxGL running on the same thread
@@ -280,7 +282,7 @@ QMapboxGL::QMapboxGL(QObject *parent, const QMapboxGLSettings &settings)
loop.setLocalData(std::make_shared<mbgl::util::RunLoop>());
}
- d_ptr = new QMapboxGLPrivate(this, settings);
+ d_ptr = new QMapboxGLPrivate(this, settings, size, pixelRatio);
}
QMapboxGL::~QMapboxGL()
@@ -602,15 +604,14 @@ void QMapboxGL::rotateBy(const QPointF &first, const QPointF &second)
mbgl::ScreenCoordinate { second.x(), second.y() });
}
-void QMapboxGL::resize(const QSize& size)
+void QMapboxGL::resize(const QSize& size, const QSize& framebufferSize)
{
- QSize converted = size / d_ptr->getPixelRatio();
- if (d_ptr->size == converted) return;
+ if (d_ptr->size == size && d_ptr->fbSize == framebufferSize) return;
- glViewport(0, 0, converted.width(), converted.height());
+ d_ptr->size = size;
+ d_ptr->fbSize = framebufferSize;
- d_ptr->size = converted;
- d_ptr->mapObj->update(mbgl::Update::Dimensions);
+ d_ptr->mapObj->setSize({{ static_cast<uint16_t>(size.width()), static_cast<uint16_t>(size.height()) }});
}
void QMapboxGL::addAnnotationIcon(const QString &name, const QImage &sprite)
@@ -793,19 +794,29 @@ void QMapboxGL::setFilter(const QString& layer_, const QVariant& filter_)
qWarning() << "Layer doesn't support filters";
}
+#if QT_VERSION >= 0x050000
+void QMapboxGL::render(QOpenGLFramebufferObject *fbo)
+{
+ d_ptr->dirty = false;
+ d_ptr->updateFramebufferBinding(fbo);
+ d_ptr->mapObj->render(*d_ptr);
+}
+#else
void QMapboxGL::render()
{
d_ptr->dirty = false;
- d_ptr->mapObj->render();
+ d_ptr->mapObj->render(*d_ptr);
}
+#endif
void QMapboxGL::connectionEstablished()
{
d_ptr->connectionEstablished();
}
-QMapboxGLPrivate::QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &settings)
+QMapboxGLPrivate::QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &settings, const QSize &size_, qreal pixelRatio)
: QObject(q)
+ , size(size_)
, q_ptr(q)
, fileSourceObj(std::make_unique<mbgl::DefaultFileSource>(
settings.cacheDatabasePath().toStdString(),
@@ -813,7 +824,8 @@ QMapboxGLPrivate::QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &settin
settings.cacheDatabaseMaximumSize()))
, threadPool(4)
, mapObj(std::make_unique<mbgl::Map>(
- *this, *this, getPixelRatio(), *fileSourceObj, threadPool,
+ *this, std::array<uint16_t, 2>{{ static_cast<uint16_t>(size.width()), static_cast<uint16_t>(size.height()) }},
+ pixelRatio, *fileSourceObj, threadPool,
static_cast<mbgl::MapMode>(settings.mapMode()),
static_cast<mbgl::GLContextMode>(settings.contextMode()),
static_cast<mbgl::ConstrainMode>(settings.constrainMode()),
@@ -830,36 +842,42 @@ QMapboxGLPrivate::~QMapboxGLPrivate()
{
}
-float QMapboxGLPrivate::getPixelRatio() const
-{
#if QT_VERSION >= 0x050000
- // QWindow is the most reliable pixel ratio because QGuiApplication returns
- // the maximum pixel ratio of all available QScreen objects - this is not
- // valid for cases e.g. where two or more QScreen objects with different
- // pixel ratios are present and the window shows on the screen with lower
- // pixel ratio.
- static const float pixelRatio = QGuiApplication::allWindows().first()->devicePixelRatio();
-#else
- static const float pixelRatio = 1.0;
-#endif
- return pixelRatio;
+void QMapboxGLPrivate::updateFramebufferBinding(QOpenGLFramebufferObject *fbo_)
+{
+ fbo = fbo_;
+ if (fbo) {
+ getContext().bindFramebuffer.setDirty();
+ getContext().viewport.setCurrentValue(
+ { 0, 0, static_cast<uint16_t>(fbo->width()), static_cast<uint16_t>(fbo->height()) });
+ } else {
+ getContext().bindFramebuffer.setCurrentValue(0);
+ getContext().viewport.setCurrentValue({ 0, 0, static_cast<uint16_t>(fbSize.width()),
+ static_cast<uint16_t>(fbSize.height()) });
+ }
}
void QMapboxGLPrivate::bind()
{
- MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0));
-}
-
-std::array<uint16_t, 2> QMapboxGLPrivate::getSize() const
-{
- return {{ static_cast<uint16_t>(size.width()), static_cast<uint16_t>(size.height()) }};
+ if (fbo) {
+ fbo->bind();
+ getContext().bindFramebuffer.setDirty();
+ getContext().viewport = { 0, 0, static_cast<uint16_t>(fbo->width()),
+ static_cast<uint16_t>(fbo->height()) };
+ } else {
+ getContext().bindFramebuffer = 0;
+ getContext().viewport = { 0, 0, static_cast<uint16_t>(fbSize.width()),
+ static_cast<uint16_t>(fbSize.height()) };
+ }
}
-
-std::array<uint16_t, 2> QMapboxGLPrivate::getFramebufferSize() const
+#else
+void QMapboxGLPrivate::bind()
{
- return {{ static_cast<uint16_t>(size.width() * getPixelRatio()),
- static_cast<uint16_t>(size.height() * getPixelRatio()) }};
+ getContext().bindFramebuffer = 0;
+ getContext().viewport = { 0, 0, static_cast<uint16_t>(fbSize.width()),
+ static_cast<uint16_t>(fbSize.height()) };
}
+#endif
void QMapboxGLPrivate::invalidate()
{
diff --git a/platform/qt/src/qmapboxgl_p.hpp b/platform/qt/src/qmapboxgl_p.hpp
index 5a228896dc..e7a14601c1 100644
--- a/platform/qt/src/qmapboxgl_p.hpp
+++ b/platform/qt/src/qmapboxgl_p.hpp
@@ -17,22 +17,27 @@ class QMapboxGLPrivate : public QObject, public mbgl::View, public mbgl::Backend
Q_OBJECT
public:
- explicit QMapboxGLPrivate(QMapboxGL *, const QMapboxGLSettings &);
+ explicit QMapboxGLPrivate(QMapboxGL *, const QMapboxGLSettings &, const QSize &size, qreal pixelRatio);
virtual ~QMapboxGLPrivate();
// mbgl::View implementation.
float getPixelRatio() const;
void bind() final;
- std::array<uint16_t, 2> getSize() const final;
- std::array<uint16_t, 2> getFramebufferSize() const final;
+ std::array<uint16_t, 2> getSize() const;
+ std::array<uint16_t, 2> getFramebufferSize() const;
void activate() final {}
void deactivate() final {}
void invalidate() final;
void notifyMapChange(mbgl::MapChange) final;
+#if QT_VERSION >= 0x050000
+ void updateFramebufferBinding(QOpenGLFramebufferObject *);
+#endif
+
mbgl::EdgeInsets margins;
QSize size { 0, 0 };
+ QSize fbSize { 0, 0 };
QMapboxGL *q_ptr { nullptr };
@@ -42,6 +47,8 @@ public:
bool dirty { false };
+ QOpenGLFramebufferObject *fbo { nullptr };
+
public slots:
void connectionEstablished();
diff --git a/platform/qt/src/qquickmapboxglrenderer.cpp b/platform/qt/src/qquickmapboxglrenderer.cpp
index d550794d64..903e1c0b05 100644
--- a/platform/qt/src/qquickmapboxglrenderer.cpp
+++ b/platform/qt/src/qquickmapboxglrenderer.cpp
@@ -19,7 +19,7 @@ QQuickMapboxGLRenderer::QQuickMapboxGLRenderer()
settings.setCacheDatabaseMaximumSize(20 * 1024 * 1024);
settings.setViewportMode(QMapboxGLSettings::FlippedYViewport);
- m_map.reset(new QMapboxGL(nullptr, settings));
+ m_map.reset(new QMapboxGL(nullptr, settings, QSize(256, 256), 1));
}
QQuickMapboxGLRenderer::~QQuickMapboxGLRenderer()
@@ -28,7 +28,7 @@ QQuickMapboxGLRenderer::~QQuickMapboxGLRenderer()
QOpenGLFramebufferObject* QQuickMapboxGLRenderer::createFramebufferObject(const QSize &size)
{
- m_map->resize(size);
+ m_map->resize(size / m_pixelRatio, size);
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
@@ -38,7 +38,7 @@ QOpenGLFramebufferObject* QQuickMapboxGLRenderer::createFramebufferObject(const
void QQuickMapboxGLRenderer::render()
{
- m_map->render();
+ m_map->render(framebufferObject());
}
void QQuickMapboxGLRenderer::synchronize(QQuickFramebufferObject *item)
@@ -51,6 +51,12 @@ void QQuickMapboxGLRenderer::synchronize(QQuickFramebufferObject *item)
m_initialized = true;
}
+ if (auto window = quickMap->window()) {
+ m_pixelRatio = window->devicePixelRatio();
+ } else {
+ m_pixelRatio = 1;
+ }
+
auto syncStatus = quickMap->m_syncState;
quickMap->m_syncState = QQuickMapboxGL::NothingNeedsSync;
diff --git a/platform/qt/src/qquickmapboxglrenderer.hpp b/platform/qt/src/qquickmapboxglrenderer.hpp
index e0fc767d58..7adeea0421 100644
--- a/platform/qt/src/qquickmapboxglrenderer.hpp
+++ b/platform/qt/src/qquickmapboxglrenderer.hpp
@@ -29,6 +29,7 @@ signals:
private:
bool m_initialized = false;
+ qreal m_pixelRatio = 1;
QScopedPointer<QMapboxGL> m_map;
};
diff --git a/platform/qt/test/headless_view_qt.cpp b/platform/qt/test/headless_view_qt.cpp
deleted file mode 100644
index 133b4a2371..0000000000
--- a/platform/qt/test/headless_view_qt.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include <mbgl/platform/default/headless_view.hpp>
-
-#include <mbgl/gl/gl.hpp>
-
-#include <QApplication>
-#include <QGLContext>
-#include <QGLWidget>
-
-#if QT_VERSION >= 0x050000
-#include <QOpenGLContext>
-#endif
-
-#include <cassert>
-
-namespace mbgl {
-
-void HeadlessView::bindFramebuffer() {
- assert(fbo);
- MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
-}
-
-void HeadlessView::resizeFramebuffer() {
- const unsigned int w = dimensions[0] * pixelRatio;
- const unsigned int h = dimensions[1] * pixelRatio;
-
- // Create depth/stencil buffer
- MBGL_CHECK_ERROR(glGenRenderbuffersEXT(1, &fboDepthStencil));
- MBGL_CHECK_ERROR(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboDepthStencil));
- MBGL_CHECK_ERROR(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, w, h));
- MBGL_CHECK_ERROR(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0));
-
- MBGL_CHECK_ERROR(glGenRenderbuffersEXT(1, &fboColor));
- MBGL_CHECK_ERROR(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboColor));
- MBGL_CHECK_ERROR(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, w, h));
- MBGL_CHECK_ERROR(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0));
-
- MBGL_CHECK_ERROR(glGenFramebuffersEXT(1, &fbo));
- MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
-
- MBGL_CHECK_ERROR(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, fboColor));
- MBGL_CHECK_ERROR(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER_EXT, fboDepthStencil));
-
- GLenum status = MBGL_CHECK_ERROR(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
-
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- std::string error("Couldn't create framebuffer: ");
- switch (status) {
- case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: (error += "incomplete attachment"); break;
- case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: error += "incomplete missing attachment"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: error += "incomplete dimensions"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: error += "incomplete formats"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: error += "incomplete draw buffer"; break;
- case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: error += "incomplete read buffer"; break;
- case GL_FRAMEBUFFER_UNSUPPORTED: error += "unsupported"; break;
- default: error += "other"; break;
- }
- throw std::runtime_error(error);
- }
-
- MBGL_CHECK_ERROR(glViewport(0, 0, w, h));
-}
-
-void HeadlessView::clearBuffers() {
- MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
-
- if (fbo) {
- MBGL_CHECK_ERROR(glDeleteFramebuffersEXT(1, &fbo));
- fbo = 0;
- }
-
- if (fboColor) {
- MBGL_CHECK_ERROR(glDeleteRenderbuffersEXT(1, &fboColor));
- fboColor = 0;
- }
-
- if (fboDepthStencil) {
- MBGL_CHECK_ERROR(glDeleteRenderbuffersEXT(1, &fboDepthStencil));
- fboDepthStencil = 0;
- }
-}
-
-} // namespace mbgl
diff --git a/platform/qt/test/qmapboxgl.cpp b/platform/qt/test/qmapboxgl.cpp
index 8bcc485d89..597aef5df3 100644
--- a/platform/qt/test/qmapboxgl.cpp
+++ b/platform/qt/test/qmapboxgl.cpp
@@ -19,7 +19,7 @@ public:
widget.makeCurrent();
QMapbox::initializeGLExtensions();
- map.resize(QSize(512, 512));
+ map.resize(QSize(512, 512), QSize(512, 512));
map.setCoordinateZoom(QMapbox::Coordinate(60.170448, 24.942046), 14);
}