1 /****************************************************************************
2 **
3 ** Copyright (C) 2017 The Qt Company Ltd.
4 ** Copyright (C) 2017 Mapbox, Inc.
5 ** Contact: http://www.qt.io/licensing/
6 **
7 ** This file is part of the QtLocation module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL3$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see http://www.qt.io/terms-conditions. For further
16 ** information use the contact form at http://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPLv3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or later as published by the Free
29 ** Software Foundation and appearing in the file LICENSE.GPL included in
30 ** the packaging of this file. Please review the following information to
31 ** ensure the GNU General Public License version 2.0 requirements will be
32 ** met: http://www.gnu.org/licenses/gpl-2.0.html.
33 **
34 ** $QT_END_LICENSE$
35 **
36 ****************************************************************************/
37
38 #include "qsgmapboxglnode.h"
39 #include "qgeomapmapboxgl.h"
40
41 #if QT_HAS_INCLUDE(<QtQuick/private/qsgplaintexture_p.h>)
42 #include <QtQuick/private/qsgplaintexture_p.h>
43 #endif
44
45 #include <QtGui/QOpenGLContext>
46 #include <QtGui/QOpenGLFunctions>
47
48 // QSGMapboxGLTextureNode
49
50 static const QSize minTextureSize = QSize(64, 64);
51
QSGMapboxGLTextureNode(const QMapboxGLSettings & settings,const QSize & size,qreal pixelRatio,QGeoMapMapboxGL * geoMap)52 QSGMapboxGLTextureNode::QSGMapboxGLTextureNode(const QMapboxGLSettings &settings, const QSize &size, qreal pixelRatio, QGeoMapMapboxGL *geoMap)
53 : QSGSimpleTextureNode()
54 {
55 setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically);
56 setFiltering(QSGTexture::Linear);
57
58 m_map.reset(new QMapboxGL(nullptr, settings, size.expandedTo(minTextureSize), pixelRatio));
59
60 QObject::connect(m_map.data(), &QMapboxGL::needsRendering, geoMap, &QGeoMap::sgNodeChanged);
61 QObject::connect(m_map.data(), &QMapboxGL::copyrightsChanged, geoMap,
62 static_cast<void (QGeoMap::*)(const QString &)>(&QGeoMapMapboxGL::copyrightsChanged));
63 }
64
resize(const QSize & size,qreal pixelRatio)65 void QSGMapboxGLTextureNode::resize(const QSize &size, qreal pixelRatio)
66 {
67 const QSize& minSize = size.expandedTo(minTextureSize);
68 const QSize fbSize = minSize * pixelRatio;
69 m_map->resize(minSize);
70
71 m_fbo.reset(new QOpenGLFramebufferObject(fbSize, QOpenGLFramebufferObject::CombinedDepthStencil));
72 m_map->setFramebufferObject(m_fbo->handle(), fbSize);
73
74 QSGPlainTexture *fboTexture = static_cast<QSGPlainTexture *>(texture());
75 if (!fboTexture) {
76 fboTexture = new QSGPlainTexture;
77 fboTexture->setHasAlphaChannel(true);
78 }
79
80 fboTexture->setTextureId(m_fbo->texture());
81 fboTexture->setTextureSize(fbSize);
82
83 if (!texture()) {
84 setTexture(fboTexture);
85 setOwnsTexture(true);
86 }
87
88 setRect(QRectF(QPointF(), minSize));
89 markDirty(QSGNode::DirtyGeometry);
90 }
91
render(QQuickWindow * window)92 void QSGMapboxGLTextureNode::render(QQuickWindow *window)
93 {
94 QOpenGLFunctions *f = window->openglContext()->functions();
95 f->glViewport(0, 0, m_fbo->width(), m_fbo->height());
96
97 GLint alignment;
98 f->glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
99
100 m_fbo->bind();
101
102 f->glClearColor(0.f, 0.f, 0.f, 0.f);
103 f->glColorMask(true, true, true, true);
104 f->glClear(GL_COLOR_BUFFER_BIT);
105
106 m_map->render();
107 m_fbo->release();
108
109 // QTBUG-62861
110 f->glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
111
112 window->resetOpenGLState();
113 markDirty(QSGNode::DirtyMaterial);
114 }
115
map() const116 QMapboxGL* QSGMapboxGLTextureNode::map() const
117 {
118 return m_map.data();
119 }
120
121 // QSGMapboxGLRenderNode
122
QSGMapboxGLRenderNode(const QMapboxGLSettings & settings,const QSize & size,qreal pixelRatio,QGeoMapMapboxGL * geoMap)123 QSGMapboxGLRenderNode::QSGMapboxGLRenderNode(const QMapboxGLSettings &settings, const QSize &size, qreal pixelRatio, QGeoMapMapboxGL *geoMap)
124 : QSGRenderNode()
125 {
126 m_map.reset(new QMapboxGL(nullptr, settings, size, pixelRatio));
127 QObject::connect(m_map.data(), &QMapboxGL::needsRendering, geoMap, &QGeoMap::sgNodeChanged);
128 QObject::connect(m_map.data(), &QMapboxGL::copyrightsChanged, geoMap,
129 static_cast<void (QGeoMap::*)(const QString &)>(&QGeoMapMapboxGL::copyrightsChanged));
130 }
131
map() const132 QMapboxGL* QSGMapboxGLRenderNode::map() const
133 {
134 return m_map.data();
135 }
136
render(const RenderState * state)137 void QSGMapboxGLRenderNode::render(const RenderState *state)
138 {
139 // QMapboxGL assumes we've prepared the viewport prior to render().
140 QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
141 f->glViewport(state->scissorRect().x(), state->scissorRect().y(), state->scissorRect().width(), state->scissorRect().height());
142 f->glScissor(state->scissorRect().x(), state->scissorRect().y(), state->scissorRect().width(), state->scissorRect().height());
143 f->glEnable(GL_SCISSOR_TEST);
144
145 GLint alignment;
146 f->glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
147
148 m_map->render();
149
150 // QTBUG-62861
151 f->glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
152 }
153
changedStates() const154 QSGRenderNode::StateFlags QSGMapboxGLRenderNode::changedStates() const
155 {
156 return QSGRenderNode::DepthState
157 | QSGRenderNode::StencilState
158 | QSGRenderNode::ScissorState
159 | QSGRenderNode::ColorState
160 | QSGRenderNode::BlendState
161 | QSGRenderNode::ViewportState
162 | QSGRenderNode::RenderTargetState;
163 }
164
165