Source code

Revision control

Copy as Markdown

// Copyright (C) 2017 The Qt Company Ltd.
// Copyright (C) 2017 Mapbox, Inc.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qsgmapboxglnode.h"
#include "qgeomapmapboxgl.h"
#if __has_include(<QtQuick/private/qsgplaintexture_p.h>)
#include <QtQuick/private/qsgplaintexture_p.h>
#endif
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
// QSGMapboxGLTextureNode
static const QSize minTextureSize = QSize(64, 64);
QSGMapboxGLTextureNode::QSGMapboxGLTextureNode(const QMapboxGLSettings &settings, const QSize &size, qreal pixelRatio, QGeoMapMapboxGL *geoMap)
: QSGSimpleTextureNode()
{
setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically);
setFiltering(QSGTexture::Linear);
m_map.reset(new QMapboxGL(nullptr, settings, size.expandedTo(minTextureSize), pixelRatio));
QObject::connect(m_map.data(), &QMapboxGL::needsRendering, geoMap, &QGeoMap::sgNodeChanged);
QObject::connect(m_map.data(), &QMapboxGL::copyrightsChanged, geoMap,
static_cast<void (QGeoMap::*)(const QString &)>(&QGeoMapMapboxGL::copyrightsChanged));
}
void QSGMapboxGLTextureNode::resize(const QSize &size, qreal pixelRatio)
{
const QSize& minSize = size.expandedTo(minTextureSize);
const QSize fbSize = minSize * pixelRatio;
m_map->resize(minSize);
m_fbo.reset(new QOpenGLFramebufferObject(fbSize, QOpenGLFramebufferObject::CombinedDepthStencil));
m_map->setFramebufferObject(m_fbo->handle(), fbSize);
QSGPlainTexture *fboTexture = static_cast<QSGPlainTexture *>(texture());
if (!fboTexture) {
fboTexture = new QSGPlainTexture;
fboTexture->setHasAlphaChannel(true);
}
fboTexture->setTextureId(m_fbo->texture());
fboTexture->setTextureSize(fbSize);
if (!texture()) {
setTexture(fboTexture);
setOwnsTexture(true);
}
setRect(QRectF(QPointF(), minSize));
markDirty(QSGNode::DirtyGeometry);
}
void QSGMapboxGLTextureNode::render(QQuickWindow *window)
{
QOpenGLFunctions *f = window->openglContext()->functions();
f->glViewport(0, 0, m_fbo->width(), m_fbo->height());
GLint alignment;
f->glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
m_fbo->bind();
f->glClearColor(0.f, 0.f, 0.f, 0.f);
f->glColorMask(true, true, true, true);
f->glClear(GL_COLOR_BUFFER_BIT);
m_map->render();
m_fbo->release();
// QTBUG-62861
f->glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
window->resetOpenGLState();
markDirty(QSGNode::DirtyMaterial);
}
QMapboxGL* QSGMapboxGLTextureNode::map() const
{
return m_map.data();
}
// QSGMapboxGLRenderNode
QSGMapboxGLRenderNode::QSGMapboxGLRenderNode(const QMapboxGLSettings &settings, const QSize &size, qreal pixelRatio, QGeoMapMapboxGL *geoMap)
: QSGRenderNode()
{
m_map.reset(new QMapboxGL(nullptr, settings, size, pixelRatio));
QObject::connect(m_map.data(), &QMapboxGL::needsRendering, geoMap, &QGeoMap::sgNodeChanged);
QObject::connect(m_map.data(), &QMapboxGL::copyrightsChanged, geoMap,
static_cast<void (QGeoMap::*)(const QString &)>(&QGeoMapMapboxGL::copyrightsChanged));
}
QMapboxGL* QSGMapboxGLRenderNode::map() const
{
return m_map.data();
}
void QSGMapboxGLRenderNode::render(const RenderState *state)
{
// QMapboxGL assumes we've prepared the viewport prior to render().
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glViewport(state->scissorRect().x(), state->scissorRect().y(), state->scissorRect().width(), state->scissorRect().height());
f->glScissor(state->scissorRect().x(), state->scissorRect().y(), state->scissorRect().width(), state->scissorRect().height());
f->glEnable(GL_SCISSOR_TEST);
GLint alignment;
f->glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
m_map->render();
// QTBUG-62861
f->glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
}
QSGRenderNode::StateFlags QSGMapboxGLRenderNode::changedStates() const
{
return QSGRenderNode::DepthState
| QSGRenderNode::StencilState
| QSGRenderNode::ScissorState
| QSGRenderNode::ColorState
| QSGRenderNode::BlendState
| QSGRenderNode::ViewportState
| QSGRenderNode::RenderTargetState;
}