diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2016-10-10 17:16:37 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2016-10-25 13:52:36 -0700 |
commit | a4d259c33f9bb890bba97fd89552720e3e0ec09b (patch) | |
tree | 342ecc27a6993c48f3a2e1d739fce890350bc44d /platform/qt | |
parent | 5cc390d694fc7510d445310d8eb9e32429a5e67b (diff) | |
download | qtlocation-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.cpp | 26 | ||||
-rw-r--r-- | platform/qt/app/mapwindow.hpp | 2 | ||||
-rw-r--r-- | platform/qt/config.cmake | 3 | ||||
-rw-r--r-- | platform/qt/include/qmapboxgl.hpp | 13 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl.cpp | 84 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl_p.hpp | 13 | ||||
-rw-r--r-- | platform/qt/src/qquickmapboxglrenderer.cpp | 12 | ||||
-rw-r--r-- | platform/qt/src/qquickmapboxglrenderer.hpp | 1 | ||||
-rw-r--r-- | platform/qt/test/headless_view_qt.cpp | 82 | ||||
-rw-r--r-- | platform/qt/test/qmapboxgl.cpp | 2 |
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 ¢er = 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); } |