diff options
Diffstat (limited to 'src/quick/scenegraph')
61 files changed, 1172 insertions, 919 deletions
diff --git a/src/quick/scenegraph/adaptations/adaptations.pri b/src/quick/scenegraph/adaptations/adaptations.pri index 6b670b12f4..a3738d6b82 100644 --- a/src/quick/scenegraph/adaptations/adaptations.pri +++ b/src/quick/scenegraph/adaptations/adaptations.pri @@ -1,3 +1,2 @@ -include(dummy/dummy.pri) include(software/software.pri) config_d3d12: include(d3d12/d3d12.pri) diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp index 5c0d739c01..7c1807466c 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp @@ -95,7 +95,7 @@ QSize QSGD3D12Context::minimumFBOSize() const QSurfaceFormat QSGD3D12Context::defaultSurfaceFormat() const { - return QSGContext::defaultSurfaceFormat(); + return QSurfaceFormat::defaultFormat(); } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h index 8ef1281554..15ce86c967 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h @@ -55,6 +55,7 @@ #include <QImage> #include <QVector4D> #include <qsggeometry.h> +#include <qt_windows.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp index 6c137a718e..37cdc89ffe 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp @@ -123,7 +123,7 @@ void QSGD3D12Layer::setRecursive(bool recursive) } -void QSGD3D12Layer::setFormat(GLenum format) +void QSGD3D12Layer::setFormat(uint format) { } diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h index cfd15ae761..55883a1fad 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h @@ -79,7 +79,7 @@ public: QImage toImage() const override; void setLive(bool live) override; void setRecursive(bool recursive) override; - void setFormat(GLenum format) override; + void setFormat(uint format) override; void setHasMipmaps(bool mipmap) override; void setDevicePixelRatio(qreal ratio) override; void setMirrorHorizontal(bool mirror) override; diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp index e2b91619cc..af3e8e36ee 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext.cpp @@ -56,11 +56,6 @@ QSGD3D12RenderContext::QSGD3D12RenderContext(QSGContext *ctx) { } -void QSGD3D12RenderContext::initialize(QOpenGLContext *) -{ - Q_UNREACHABLE(); -} - void QSGD3D12RenderContext::invalidate() { if (Q_UNLIKELY(debug_render())) @@ -98,9 +93,9 @@ QSGTexture *QSGD3D12RenderContext::createTexture(const QImage &image, uint flags return new QSGD3D12Renderer(this); } -void QSGD3D12RenderContext::renderNextFrame(QSGRenderer *renderer, GLuint fbo) +void QSGD3D12RenderContext::renderNextFrame(QSGRenderer *renderer, uint fbo) { - QSGRenderContext::renderNextFrame(renderer, fbo); + static_cast<QSGD3D12Renderer *>(renderer)->renderScene(fbo); } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h index 2e05632ad9..1acb7e4205 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12rendercontext_p.h @@ -61,10 +61,8 @@ class QSGD3D12RenderContext : public QSGRenderContext { public: QSGD3D12RenderContext(QSGContext *ctx); - - void initialize(QOpenGLContext *) override; // not in use void invalidate() override; - void renderNextFrame(QSGRenderer *renderer, GLuint fbo) override; + void renderNextFrame(QSGRenderer *renderer, uint fbo) override; QSGTexture *createTexture(const QImage &image, uint flags) const override; QSGRenderer *createRenderer() override; diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp index 79db0eba42..f6bd725e44 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12renderer.cpp @@ -657,7 +657,7 @@ void QSGD3D12Renderer::renderStencilClip(const QSGClipNode *clip, int elementInd const QSGGeometry *g = clip->geometry(); Q_ASSERT(g->attributeCount() == 1); Q_ASSERT(g->attributes()[0].tupleSize == 2); - Q_ASSERT(g->attributes()[0].type == GL_FLOAT); + Q_ASSERT(g->attributes()[0].type == QSGGeometry::TypeFloat); setInputLayout(g, &sps); m_engine->finalizePipeline(sps); diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h index 510bb65139..b9d53dd1e6 100644 --- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h +++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h @@ -52,6 +52,7 @@ // #include <qsgtexture.h> +#include <basetsd.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/dummy/dummy.pri b/src/quick/scenegraph/adaptations/dummy/dummy.pri deleted file mode 100644 index f81655dcaa..0000000000 --- a/src/quick/scenegraph/adaptations/dummy/dummy.pri +++ /dev/null @@ -1,5 +0,0 @@ -SOURCES += \ - $$PWD/qsgdummyadaptation.cpp - -HEADERS += \ - $$PWD/qsgdummyadaptation_p.h diff --git a/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation.cpp b/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation.cpp deleted file mode 100644 index 98f6872533..0000000000 --- a/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQuick module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgdummyadaptation_p.h" - -#include <private/qguiapplication_p.h> -#include <qpa/qplatformintegration.h> - -QT_BEGIN_NAMESPACE - -class QSGDummyContext : public QSGContext -{ -public: - QSGDummyContext(QObject *parent = 0) : QSGContext(parent) { } - - QSGRenderContext *createRenderContext() override { return QSGContext::createRenderContext(); } - QSGRectangleNode *createRectangleNode() override { return QSGContext::createRectangleNode(); } - QSGImageNode *createImageNode() override { return QSGContext::createImageNode(); } - QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override { return QSGContext::createPainterNode(item); } - QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override { return QSGContext::createGlyphNode(rc, preferNativeGlyphNode); } - QSGNinePatchNode *createNinePatchNode() override { return QSGContext::createNinePatchNode(); } - QSGLayer *createLayer(QSGRenderContext *rc) override { return QSGContext::createLayer(rc); } - QSurfaceFormat defaultSurfaceFormat() const override { return QSGContext::defaultSurfaceFormat(); } -}; - -QSGDummyAdaptation::QSGDummyAdaptation(QObject *parent) - : QSGContextPlugin(parent) -{ -} - -QStringList QSGDummyAdaptation::keys() const -{ - return QStringList() << QLatin1String("dummy"); -} - -QSGContext *QSGDummyAdaptation::create(const QString &) const -{ - if (!contextInstance) { - qDebug("Creating OpenGL SG context via dummy"); - contextInstance = new QSGDummyContext; - } - - return contextInstance; -} - -QSGRenderLoop *QSGDummyAdaptation::createWindowManager() -{ - qDebug("Creating default OpenGL render loop via dummy"); - return nullptr; -} - -QSGDummyContext *QSGDummyAdaptation::contextInstance = nullptr; - -QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp index 307ab206e2..04fc6da84e 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -57,10 +57,6 @@ #include <QtQuick/QSGVertexColorMaterial> #include <QtQuick/QSGOpaqueTextureMaterial> #include <QtQuick/QSGTextureMaterial> -#include <private/qsgdefaultimagenode_p.h> -#include <private/qsgdefaultrectanglenode_p.h> -#include <private/qsgdistancefieldglyphnode_p_p.h> -#include <private/qsgdefaultglyphnode_p.h> #ifndef QSG_NO_RENDERER_TIMING static bool qsg_render_timing = !qgetenv("QSG_RENDER_TIMING").isEmpty(); @@ -100,7 +96,6 @@ QSGSoftwareRenderContext::QSGSoftwareRenderContext(QSGContext *ctx) QSGSoftwareContext::QSGSoftwareContext(QObject *parent) : QSGContext(parent) { - setDistanceFieldEnabled(false); } QSGRectangleNode *QSGSoftwareContext::createRectangleNode() @@ -144,12 +139,6 @@ QSurfaceFormat QSGSoftwareContext::defaultSurfaceFormat() const return format; } -void QSGSoftwareRenderContext::initialize(QOpenGLContext *context) -{ - Q_UNUSED(context) - Q_UNREACHABLE(); -} - void QSGSoftwareRenderContext::initializeIfNeeded() { if (m_initialized) @@ -175,9 +164,9 @@ QSGRenderer *QSGSoftwareRenderContext::createRenderer() } -void QSGSoftwareRenderContext::renderNextFrame(QSGRenderer *renderer, GLuint fbo) +void QSGSoftwareRenderContext::renderNextFrame(QSGRenderer *renderer, uint fbo) { - QSGRenderContext::renderNextFrame(renderer, fbo); + renderer->renderScene(fbo); } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h index 51e69d95ed..a150676ea1 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h @@ -55,12 +55,12 @@ QT_BEGIN_NAMESPACE class QSGSoftwareRenderContext : public QSGRenderContext { + Q_OBJECT public: QSGSoftwareRenderContext(QSGContext *ctx); - void initialize(QOpenGLContext *context) override; void initializeIfNeeded(); void invalidate() override; - void renderNextFrame(QSGRenderer *renderer, GLuint fbo) override; + void renderNextFrame(QSGRenderer *renderer, uint fbo) override; QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const override; QSGRenderer *createRenderer() override; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp index 39e12c8797..7020283898 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp @@ -163,7 +163,7 @@ void QSGSoftwareLayer::setRecursive(bool recursive) m_recursive = recursive; } -void QSGSoftwareLayer::setFormat(GLenum) +void QSGSoftwareLayer::setFormat(uint) { } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h index 2fc1948f68..7c0027d3a2 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h @@ -77,7 +77,7 @@ public: QImage toImage() const override; void setLive(bool live) override; void setRecursive(bool recursive) override; - void setFormat(GLenum) override; + void setFormat(uint) override; void setHasMipmaps(bool) override; void setDevicePixelRatio(qreal ratio) override; void setMirrorHorizontal(bool mirror) override; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp index c04dea3d8f..acc55bb2db 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp @@ -58,7 +58,7 @@ QSGSoftwarePixmapRenderer::~QSGSoftwarePixmapRenderer() } -void QSGSoftwarePixmapRenderer::renderScene(GLuint) +void QSGSoftwarePixmapRenderer::renderScene(uint) { class B : public QSGBindable { diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h index 86c886d263..1c4cff06da 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer_p.h @@ -50,7 +50,7 @@ public: QSGSoftwarePixmapRenderer(QSGRenderContext *context); virtual ~QSGSoftwarePixmapRenderer(); - void renderScene(GLuint fboId = 0) final; + void renderScene(uint fboId = 0) final; void render() final; void render(QPixmap *target); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp index 8f143f3984..1858ef899c 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp @@ -49,7 +49,6 @@ #include <QtQuick/QSGSimpleRectNode> #include <QtQuick/qsgsimpletexturenode.h> #include <private/qsgtexture_p.h> -#include <private/qquickshadereffectnode_p.h> Q_LOGGING_CATEGORY(lcRenderable, "qt.scenegraph.softwarecontext.renderable") diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp index 4397178c7d..939178e532 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp @@ -62,7 +62,7 @@ QSGSoftwareRenderer::~QSGSoftwareRenderer() { } -void QSGSoftwareRenderer::renderScene(GLuint) +void QSGSoftwareRenderer::renderScene(uint) { class B : public QSGBindable { diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h index 9f558a46d5..daa5e2cd7c 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h @@ -61,7 +61,7 @@ public: QBackingStore *backingStore() const { return m_backingStore.data(); } protected: - void renderScene(GLuint fboId = 0) final; + void renderScene(uint fboId = 0) final; void render() final; private: diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h index e02fb819fe..50b9879659 100644 --- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h +++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h @@ -42,6 +42,10 @@ #include <QtQuick/qsgnode.h> +#ifndef GLuint +#define GLuint uint +#endif + QT_BEGIN_NAMESPACE class QSGAbstractRendererPrivate; diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index bb5476c3e2..8f08020374 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -154,8 +154,8 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material) p->bindAttributeLocation(attr[i], i); } p->bindAttributeLocation("_qt_order", i); - context->compile(s, material, qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile), 0); - context->initialize(s); + context->compileShader(s, material, qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile), 0); + context->initializeShader(s); if (!p->isLinked()) return 0; @@ -188,8 +188,8 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphContextFrame); QSGMaterialShader *s = static_cast<QSGMaterialShader *>(material->createShader()); - context->compile(s, material); - context->initialize(s); + context->compileShader(s, material); + context->initializeShader(s); shader = new Shader(); shader->program = s; @@ -751,8 +751,9 @@ static int qsg_countNodesInBatches(const QDataBuffer<Batch *> &batches) return sum; } -Renderer::Renderer(QSGRenderContext *ctx) +Renderer::Renderer(QSGDefaultRenderContext *ctx) : QSGRenderer(ctx) + , m_context(ctx) , m_opaqueRenderList(64) , m_alphaRenderList(64) , m_nextRenderOrder(0) @@ -812,7 +813,7 @@ Renderer::Renderer(QSGRenderContext *ctx) // If rendering with an OpenGL Core profile context, we need to create a VAO // to hold our vertex specification state. - if (context()->openglContext()->format().profile() == QSurfaceFormat::CoreProfile) { + if (m_context->openglContext()->format().profile() == QSurfaceFormat::CoreProfile) { m_vao = new QOpenGLVertexArrayObject(this); m_vao->create(); } @@ -1106,7 +1107,7 @@ void Renderer::nodeWasRemoved(Node *node) if (m_renderNodeElements.isEmpty()) { static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); - m_useDepthBuffer = useDepth && context()->openglContext()->format().depthBufferSize() > 0; + m_useDepthBuffer = useDepth && m_context->openglContext()->format().depthBufferSize() > 0; } } } diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index afc564710e..1c62b69769 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -54,6 +54,7 @@ // #include <private/qsgrenderer_p.h> +#include <private/qsgdefaultrendercontext_p.h> #include <private/qsgnodeupdater_p.h> #include <private/qdatabuffer_p.h> @@ -61,6 +62,8 @@ #include <QtCore/QBitArray> +#include <QtGui/QOpenGLFunctions> + QT_BEGIN_NAMESPACE class QOpenGLVertexArrayObject; @@ -534,7 +537,7 @@ public: float lastOpacity; }; - ShaderManager(QSGRenderContext *ctx) : blitProgram(0), visualizeProgram(0), context(ctx) { } + ShaderManager(QSGDefaultRenderContext *ctx) : blitProgram(0), visualizeProgram(0), context(ctx) { } ~ShaderManager() { qDeleteAll(rewrittenShaders); qDeleteAll(stockShaders); @@ -552,13 +555,13 @@ public: QOpenGLShaderProgram *blitProgram; QOpenGLShaderProgram *visualizeProgram; - QSGRenderContext *context; + QSGDefaultRenderContext *context; }; class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer, public QOpenGLFunctions { public: - Renderer(QSGRenderContext *); + Renderer(QSGDefaultRenderContext *); ~Renderer(); enum VisualizeMode { @@ -642,6 +645,7 @@ private: void visualizeDrawGeometry(const QSGGeometry *g); void setCustomRenderMode(const QByteArray &mode) Q_DECL_OVERRIDE; + QSGDefaultRenderContext *m_context; QSet<Node *> m_taggedRoots; QDataBuffer<Element *> m_opaqueRenderList; QDataBuffer<Element *> m_alphaRenderList; diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp index d1e1bc0176..64635edc4f 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.cpp +++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp @@ -39,10 +39,11 @@ #include "qsggeometry.h" #include "qsggeometry_p.h" - -#include <qopenglcontext.h> -#include <qopenglfunctions.h> -#include <private/qopenglextensions_p.h> +#ifndef QT_NO_OPENGL +# include <qopenglcontext.h> +# include <qopenglfunctions.h> +# include <private/qopenglextensions_p.h> +#endif #ifdef Q_OS_QNX #include <malloc.h> @@ -77,7 +78,7 @@ QSGGeometry::Attribute QSGGeometry::Attribute::createWithSemantic(int pos, int t const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_Point2D() { static Attribute data[] = { - Attribute::createWithSemantic(0, 2, GL_FLOAT, Attribute::POSITION) + Attribute::createWithSemantic(0, 2, TypeFloat, Attribute::POSITION) }; static AttributeSet attrs = { 1, sizeof(float) * 2, data }; return attrs; @@ -90,8 +91,8 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_Point2D() const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_TexturedPoint2D() { static Attribute data[] = { - Attribute::createWithSemantic(0, 2, GL_FLOAT, Attribute::POSITION), - Attribute::createWithSemantic(1, 2, GL_FLOAT, Attribute::TEXCOORD) + Attribute::createWithSemantic(0, 2, TypeFloat, Attribute::POSITION), + Attribute::createWithSemantic(1, 2, TypeFloat, Attribute::TEXCOORD) }; static AttributeSet attrs = { 2, sizeof(float) * 4, data }; return attrs; @@ -104,8 +105,8 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_TexturedPoint2D( const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D() { static Attribute data[] = { - Attribute::createWithSemantic(0, 2, GL_FLOAT, Attribute::POSITION), - Attribute::createWithSemantic(1, 4, GL_UNSIGNED_BYTE, Attribute::COLOR) + Attribute::createWithSemantic(0, 2, TypeFloat, Attribute::POSITION), + Attribute::createWithSemantic(1, 4, TypeUnsignedByte, Attribute::COLOR) }; static AttributeSet attrs = { 2, 2 * sizeof(float) + 4 * sizeof(char), data }; return attrs; @@ -405,7 +406,7 @@ QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes, int vertexCount, int indexCount, int indexType) - : m_drawing_mode(GL_TRIANGLE_STRIP) + : m_drawing_mode(DrawTriangleStrip) , m_vertex_count(0) , m_index_count(0) , m_index_type(indexType) @@ -421,21 +422,20 @@ QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes, Q_UNUSED(m_reserved_bits); Q_ASSERT(m_attributes.count > 0); Q_ASSERT(m_attributes.stride > 0); - +#ifndef QT_NO_OPENGL Q_ASSERT_X(indexType != GL_UNSIGNED_INT || static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions()) ->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint), "QSGGeometry::QSGGeometry", "GL_UNSIGNED_INT is not supported, geometry will not render" ); - - if (indexType != GL_UNSIGNED_BYTE - && indexType != GL_UNSIGNED_SHORT - && indexType != GL_UNSIGNED_INT) { +#endif + if (indexType != TypeUnsignedByte + && indexType != TypeUnsignedShort + && indexType != TypeUnsignedInt) { qFatal("QSGGeometry: Unsupported index type, %x.\n", indexType); } - // Because allocate reads m_vertex_count, m_index_count and m_owns_data, these // need to be set before calling allocate... allocate(vertexCount, indexCount); @@ -531,11 +531,17 @@ const void *QSGGeometry::indexData() const The default value is \c GL_TRIANGLE_STRIP. */ +#ifndef QT_NO_OPENGL void QSGGeometry::setDrawingMode(GLenum mode) { m_drawing_mode = mode; } - +#else +void QSGGeometry::setDrawingMode(int mode) +{ + m_drawing_mode = mode; +} +#endif /*! Gets the current line or point width or to be used for this geometry. This property only applies to line width when the drawingMode is \c GL_LINES, \c GL_LINE_STRIP, or @@ -612,8 +618,8 @@ void QSGGeometry::allocate(int vertexCount, int indexCount) m_index_data_offset = -1; m_owns_data = false; } else { - Q_ASSERT(m_index_type == GL_UNSIGNED_INT || m_index_type == GL_UNSIGNED_SHORT); - int indexByteSize = indexCount * (m_index_type == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32)); + Q_ASSERT(m_index_type == TypeUnsignedInt || m_index_type == TypeUnsignedShort); + int indexByteSize = indexCount * (m_index_type == TypeUnsignedShort ? sizeof(quint16) : sizeof(quint32)); m_data = (void *) malloc(vertexByteSize + indexByteSize); m_index_data_offset = vertexByteSize; m_owns_data = true; diff --git a/src/quick/scenegraph/coreapi/qsggeometry.h b/src/quick/scenegraph/coreapi/qsggeometry.h index 5d1ed7b263..8d0cd03968 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.h +++ b/src/quick/scenegraph/coreapi/qsggeometry.h @@ -144,9 +144,14 @@ public: int indexType = TypeUnsignedShort); virtual ~QSGGeometry(); +#ifndef QT_NO_OPENGL // ### Qt 6: GL types to be removed from the public API void setDrawingMode(GLenum mode); inline GLenum drawingMode() const { return m_drawing_mode; } +#else + void setDrawingMode(int mode); + inline int drawingMode() const { return m_drawing_mode; } +#endif void allocate(int vertexCount, int indexCount = 0); diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp index ceb53d0d14..42a4c4abd3 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp @@ -40,7 +40,13 @@ #include "qsgmaterial.h" #include "qsgrenderer_p.h" #include "qsgmaterialshader_p.h" -#include <private/qsgshadersourcebuilder_p.h> +#ifndef QT_NO_OPENGL +# include <private/qsgshadersourcebuilder_p.h> +# include <private/qsgdefaultcontext_p.h> +# include <private/qsgdefaultrendercontext_p.h> +# include <QtGui/QOpenGLFunctions> +# include <QtGui/QOpenGLContext> +#endif QT_BEGIN_NAMESPACE @@ -58,7 +64,7 @@ void qsg_set_material_failure() qsg_material_failure = true; } #endif - +#ifndef QT_NO_OPENGL const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType type) const { QStringList files = m_sourceFiles[type]; @@ -68,6 +74,7 @@ const char *QSGMaterialShaderPrivate::loadShaderSource(QOpenGLShader::ShaderType m_sources[type] = builder.source(); return m_sources[type].constData(); } +#endif #ifndef QT_NO_DEBUG static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK"); @@ -220,7 +227,7 @@ QSGMaterialShader::~QSGMaterialShader() defines the attribute register position in the vertex shader. */ - +#ifndef QT_NO_OPENGL /*! \fn const char *QSGMaterialShader::vertexShader() const @@ -256,7 +263,7 @@ const char *QSGMaterialShader::fragmentShader() const Returns the shader program used by this QSGMaterialShader. */ - +#endif /*! \fn void QSGMaterialShader::initialize() @@ -313,6 +320,7 @@ void QSGMaterialShader::updateState(const RenderState & /* state */, QSGMaterial { } +#ifndef QT_NO_OPENGL /*! Sets the GLSL source file for the shader stage \a type to \a sourceFile. The default implementation of the vertexShader() and fragmentShader() functions @@ -388,7 +396,7 @@ void QSGMaterialShader::compile() } } - +#endif /*! \class QSGMaterialShader::RenderState @@ -542,7 +550,7 @@ QRect QSGMaterialShader::RenderState::deviceRect() const return static_cast<const QSGRenderer *>(m_data)->deviceRect(); } - +#ifndef QT_NO_OPENGL /*! Returns the QOpenGLContext that is being used for rendering @@ -550,9 +558,15 @@ QRect QSGMaterialShader::RenderState::deviceRect() const QOpenGLContext *QSGMaterialShader::RenderState::context() const { - return static_cast<const QSGRenderer *>(m_data)->context()->openglContext(); + // Only the QSGDefaultRenderContext will have an OpenGL Context to query + auto openGLRenderContext = static_cast<const QSGDefaultRenderContext *>(static_cast<const QSGRenderer *>(m_data)->context()); + if (openGLRenderContext != nullptr) + return openGLRenderContext->openglContext(); + else + return nullptr; } +#endif #ifndef QT_NO_DEBUG static int qt_material_count = 0; diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.h b/src/quick/scenegraph/coreapi/qsgmaterial.h index 0a6a340092..13d15a089e 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.h +++ b/src/quick/scenegraph/coreapi/qsgmaterial.h @@ -41,7 +41,11 @@ #define QSGMATERIAL_H #include <QtQuick/qtquickglobal.h> -#include <QtGui/qopenglshaderprogram.h> +#ifndef QT_NO_OPENGL +# include <QtGui/qopenglshaderprogram.h> +#endif +#include <QtGui/QMatrix4x4> +#include <QtCore/QRect> QT_BEGIN_NAMESPACE @@ -77,9 +81,9 @@ public: QRect deviceRect() const; float determinant() const; float devicePixelRatio() const; - +#ifndef QT_NO_OPENGL QOpenGLContext *context() const; - +#endif private: friend class QSGRenderer; DirtyStates m_dirty; @@ -94,27 +98,30 @@ public: // First time a material is used, oldMaterial is null. virtual void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial); virtual char const *const *attributeNames() const = 0; // Array must end with null. - +#ifndef QT_NO_OPENGL inline QOpenGLShaderProgram *program() { return &m_program; } - +#endif protected: Q_DECLARE_PRIVATE(QSGMaterialShader) QSGMaterialShader(QSGMaterialShaderPrivate &dd); - friend class QSGRenderContext; + friend class QSGDefaultRenderContext; friend class QSGBatchRenderer::ShaderManager; - +#ifndef QT_NO_OPENGL void setShaderSourceFile(QOpenGLShader::ShaderType type, const QString &sourceFile); void setShaderSourceFiles(QOpenGLShader::ShaderType type, const QStringList &sourceFiles); virtual void compile(); +#endif virtual void initialize() { } - +#ifndef QT_NO_OPENGL virtual const char *vertexShader() const; virtual const char *fragmentShader() const; - +#endif private: +#ifndef QT_NO_OPENGL QOpenGLShaderProgram m_program; +#endif QScopedPointer<QSGMaterialShaderPrivate> d_ptr; }; diff --git a/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h b/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h index 291c0cc57c..0dbce010db 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h +++ b/src/quick/scenegraph/coreapi/qsgmaterialshader_p.h @@ -59,10 +59,12 @@ QT_BEGIN_NAMESPACE class Q_QUICK_PRIVATE_EXPORT QSGMaterialShaderPrivate { public: +#ifndef QT_NO_OPENGL const char *loadShaderSource(QOpenGLShader::ShaderType type) const; QHash<QOpenGLShader::ShaderType, QStringList> m_sourceFiles; mutable QHash<QOpenGLShader::ShaderType, QByteArray> m_sources; +#endif }; #ifndef QT_NO_DEBUG diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp index 223c555f3e..02c0414bc4 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.cpp +++ b/src/quick/scenegraph/coreapi/qsgnode.cpp @@ -1472,15 +1472,15 @@ QDebug operator<<(QDebug d, const QSGGeometryNode *n) } else { switch (g->drawingMode()) { - case GL_TRIANGLE_STRIP: d << "strip"; break; - case GL_TRIANGLE_FAN: d << "fan"; break; - case GL_TRIANGLES: d << "triangles"; break; + case QSGGeometry::DrawTriangleStrip: d << "strip"; break; + case QSGGeometry::DrawTriangleFan: d << "fan"; break; + case QSGGeometry::DrawTriangles: d << "triangles"; break; default: break; } d << "#V:" << g->vertexCount() << "#I:" << g->indexCount(); - if (g->attributeCount() > 0 && g->attributes()->type == GL_FLOAT) { + if (g->attributeCount() > 0 && g->attributes()->type == QSGGeometry::TypeFloat) { float x1 = 1e10, x2 = -1e10, y1=1e10, y2=-1e10; int stride = g->sizeOfVertex(); for (int i = 0; i < g->vertexCount(); ++i) { diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index ace10661c0..220e6ab212 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -39,11 +39,15 @@ #include "qsgrenderer_p.h" #include "qsgnodeupdater_p.h" - -#include <qopenglframebufferobject.h> - +#ifndef QT_NO_OPENGL +# include <QtGui/QOpenGLFramebufferObject> +# include <QtGui/QOpenGLContext> +# include <QtGui/QOpenGLFunctions> +#endif #include <private/qquickprofiler_p.h> +#include <QtCore/QElapsedTimer> + QT_BEGIN_NAMESPACE static const bool qsg_sanity_check = qEnvironmentVariableIntValue("QSG_SANITY_CHECK"); @@ -63,19 +67,25 @@ int qt_sg_envInt(const char *name, int defaultValue) void QSGBindable::clear(QSGAbstractRenderer::ClearMode mode) const { +#ifndef QT_NO_OPENGL GLuint bits = 0; if (mode & QSGAbstractRenderer::ClearColorBuffer) bits |= GL_COLOR_BUFFER_BIT; if (mode & QSGAbstractRenderer::ClearDepthBuffer) bits |= GL_DEPTH_BUFFER_BIT; if (mode & QSGAbstractRenderer::ClearStencilBuffer) bits |= GL_STENCIL_BUFFER_BIT; QOpenGLContext::currentContext()->functions()->glClear(bits); +#else + Q_UNUSED(mode) +#endif } // Reactivate the color buffer after switching to the stencil. void QSGBindable::reactivate() const { +#ifndef QT_NO_OPENGL QOpenGLContext::currentContext()->functions()->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +#endif } - +#ifndef QT_NO_OPENGL QSGBindableFboId::QSGBindableFboId(GLuint id) : m_id(id) { @@ -86,7 +96,7 @@ void QSGBindableFboId::bind() const { QOpenGLContext::currentContext()->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_id); } - +#endif /*! \class QSGRenderer \brief The renderer class is the abstract baseclass use for rendering the @@ -169,8 +179,9 @@ bool QSGRenderer::isMirrored() const return matrix(0, 0) * matrix(1, 1) - matrix(0, 1) * matrix(1, 0) > 0; } -void QSGRenderer::renderScene(GLuint fboId) +void QSGRenderer::renderScene(uint fboId) { +#ifndef QT_NO_OPENGL if (fboId) { QSGBindableFboId bindable(fboId); renderScene(bindable); @@ -182,7 +193,11 @@ void QSGRenderer::renderScene(GLuint fboId) } bindable; renderScene(bindable); } +#else + Q_UNUSED(fboId) +#endif } + void QSGRenderer::renderScene(const QSGBindable &bindable) { if (!rootNode()) @@ -207,6 +222,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) bindTime = frameTimer.nsecsElapsed(); Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame); +#ifndef QT_NO_OPENGL // Sanity check that attribute registers are disabled if (qsg_sanity_check) { GLint count = 0; @@ -219,6 +235,7 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) } } } +#endif render(); if (profileFrames) diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h index 5c7a32c161..94b78a85b4 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h @@ -86,14 +86,12 @@ public: bool isMirrored() const; void renderScene(const QSGBindable &bindable); - virtual void renderScene(GLuint fboId = 0) Q_DECL_OVERRIDE; + virtual void renderScene(uint fboId = 0) Q_DECL_OVERRIDE; virtual void nodeChanged(QSGNode *node, QSGNode::DirtyState state) Q_DECL_OVERRIDE; QSGNodeUpdater *nodeUpdater() const; void setNodeUpdater(QSGNodeUpdater *updater); - inline QSGMaterialShader::RenderState state(QSGMaterialShader::RenderState::DirtyStates dirty) const; - virtual void setCustomRenderMode(const QByteArray &) { }; void clearChangedFlag() { m_changed_emitted = false; } @@ -135,7 +133,7 @@ public: virtual void clear(QSGAbstractRenderer::ClearMode mode) const; virtual void reactivate() const; }; - +#ifndef QT_NO_OPENGL class QSGBindableFboId : public QSGBindable { public: @@ -144,7 +142,7 @@ public: private: GLuint m_id; }; - +#endif QSGMaterialShader::RenderState QSGRenderer::state(QSGMaterialShader::RenderState::DirtyStates dirty) const diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index eb6a846a81..e8ef6befcd 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -72,8 +72,11 @@ QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCach // this allows us to call pathForGlyph once and reuse the result. m_referenceFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(m_doubleGlyphResolution) * QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution)); Q_ASSERT(m_referenceFont.isValid()); - +#ifndef QT_NO_OPENGL m_coreProfile = (c->format().profile() == QSurfaceFormat::CoreProfile); +#else + Q_UNUSED(c) +#endif } QSGDistanceFieldGlyphCache::~QSGDistanceFieldGlyphCache() @@ -291,7 +294,7 @@ void QSGDistanceFieldGlyphCache::markGlyphsToRender(const QVector<glyph_t> &glyp m_pendingGlyphs.add(glyphs.at(i)); } -void QSGDistanceFieldGlyphCache::updateTexture(GLuint oldTex, GLuint newTex, const QSize &newTexSize) +void QSGDistanceFieldGlyphCache::updateTexture(uint oldTex, uint newTex, const QSize &newTexSize) { int count = m_textures.count(); for (int i = 0; i < count; ++i) { diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index 8579b0a57b..78bb07599f 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -210,7 +210,7 @@ public: virtual QImage toImage() const = 0; virtual void setLive(bool live) = 0; virtual void setRecursive(bool recursive) = 0; - virtual void setFormat(GLenum format) = 0; + virtual void setFormat(uint format) = 0; virtual void setHasMipmaps(bool mipmap) = 0; virtual void setDevicePixelRatio(qreal ratio) = 0; virtual void setMirrorHorizontal(bool mirror) = 0; @@ -295,7 +295,7 @@ public: }; struct Texture { - GLuint textureId; + uint textureId; QSize size; Texture() : textureId(0), size(QSize()) { } @@ -359,10 +359,10 @@ protected: void markGlyphsToRender(const QVector<glyph_t> &glyphs); inline void removeGlyph(glyph_t glyph); - void updateTexture(GLuint oldTex, GLuint newTex, const QSize &newTexSize); + void updateTexture(uint oldTex, uint newTex, const QSize &newTexSize); inline bool containsGlyph(glyph_t glyph); - GLuint textureIdForGlyph(glyph_t glyph) const; + uint textureIdForGlyph(glyph_t glyph) const; GlyphData &glyphData(glyph_t glyph); diff --git a/src/quick/scenegraph/qsgbasicglyphnode.cpp b/src/quick/scenegraph/qsgbasicglyphnode.cpp index cecfcbfdf9..38f650a82c 100644 --- a/src/quick/scenegraph/qsgbasicglyphnode.cpp +++ b/src/quick/scenegraph/qsgbasicglyphnode.cpp @@ -47,7 +47,7 @@ QSGBasicGlyphNode::QSGBasicGlyphNode() , m_material(0) , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0) { - m_geometry.setDrawingMode(GL_TRIANGLES); + m_geometry.setDrawingMode(QSGGeometry::DrawTriangles); setGeometry(&m_geometry); } diff --git a/src/quick/scenegraph/qsgbasicimagenode.cpp b/src/quick/scenegraph/qsgbasicimagenode.cpp index a76c788656..0f3fef5dc7 100644 --- a/src/quick/scenegraph/qsgbasicimagenode.cpp +++ b/src/quick/scenegraph/qsgbasicimagenode.cpp @@ -55,10 +55,10 @@ namespace const QSGGeometry::AttributeSet &smoothAttributeSet() { static QSGGeometry::Attribute data[] = { - QSGGeometry::Attribute::createWithSemantic(0, 2, GL_FLOAT, QSGGeometry::Attribute::POSITION), - QSGGeometry::Attribute::createWithSemantic(1, 2, GL_FLOAT, QSGGeometry::Attribute::TEXCOORD), - QSGGeometry::Attribute::createWithSemantic(2, 2, GL_FLOAT, QSGGeometry::Attribute::TEXCOORD1), - QSGGeometry::Attribute::createWithSemantic(3, 2, GL_FLOAT, QSGGeometry::Attribute::TEXCOORD2) + QSGGeometry::Attribute::createWithSemantic(0, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::POSITION), + QSGGeometry::Attribute::createWithSemantic(1, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD), + QSGGeometry::Attribute::createWithSemantic(2, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD1), + QSGGeometry::Attribute::createWithSemantic(3, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD2) }; static QSGGeometry::AttributeSet attrs = { 4, sizeof(SmoothVertex), data }; return attrs; @@ -196,7 +196,7 @@ void QSGBasicImageNode::updateGeometry() if (!t) { QSGGeometry *g = geometry(); g->allocate(4); - g->setDrawingMode(GL_TRIANGLE_STRIP); + g->setDrawingMode(QSGGeometry::DrawTriangleStrip); memset(g->vertexData(), 0, g->sizeOfVertex() * 4); } else { QRectF sourceRect = t->normalizedTextureSubRect(); @@ -244,7 +244,7 @@ void QSGBasicImageNode::updateGeometry() QSGGeometry *g = geometry(); Q_ASSERT(g != &m_geometry); g->allocate(8, 14); - g->setDrawingMode(GL_TRIANGLE_STRIP); + g->setDrawingMode(QSGGeometry::DrawTriangleStrip); SmoothVertex *vertices = reinterpret_cast<SmoothVertex *>(g->vertexData()); float delta = float(qAbs(m_targetRect.width()) < qAbs(m_targetRect.height()) ? m_targetRect.width() : m_targetRect.height()) * 0.5f; @@ -273,7 +273,7 @@ void QSGBasicImageNode::updateGeometry() memcpy(g->indexDataAsUShort(), indices, sizeof(indices)); } else { m_geometry.allocate(4); - m_geometry.setDrawingMode(GL_TRIANGLE_STRIP); + m_geometry.setDrawingMode(QSGGeometry::DrawTriangleStrip); QSGGeometry::updateTexturedRectGeometry(&m_geometry, m_targetRect, sr); } } else { @@ -375,7 +375,7 @@ void QSGBasicImageNode::updateGeometry() g->allocate(hCells * vCells * 4 + (hCells + vCells - 1) * 4, hCells * vCells * 6 + (hCells + vCells) * 12); - g->setDrawingMode(GL_TRIANGLES); + g->setDrawingMode(QSGGeometry::DrawTriangles); SmoothVertex *vertices = reinterpret_cast<SmoothVertex *>(g->vertexData()); memset(vertices, 0, g->vertexCount() * g->sizeOfVertex()); quint16 *indices = g->indexDataAsUShort(); @@ -486,7 +486,7 @@ void QSGBasicImageNode::updateGeometry() Q_ASSERT(indices - g->indexCount() == g->indexData()); } else { m_geometry.allocate(hCells * vCells * 4, hCells * vCells * 6); - m_geometry.setDrawingMode(GL_TRIANGLES); + m_geometry.setDrawingMode(QSGGeometry::DrawTriangles); QSGGeometry::TexturedPoint2D *vertices = m_geometry.vertexDataAsTexturedPoint2D(); ys = yData.data(); for (int j = 0; j < vCells; ++j, ys += 2) { diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 2ba16e7328..b0dd24af23 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -38,27 +38,13 @@ ****************************************************************************/ #include <QtQuick/private/qsgcontext_p.h> -#include <QtQuick/private/qsgbatchrenderer_p.h> -#include <QtQuick/private/qsgdistancefieldutil_p.h> -#include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h> -#include <QtQuick/private/qsgdefaultrectanglenode_p.h> -#include <QtQuick/private/qsgdefaultimagenode_p.h> -#include <QtQuick/private/qsgdefaultpainternode_p.h> -#include <QtQuick/private/qsgdefaultglyphnode_p.h> -#include <QtQuick/private/qsgdistancefieldglyphnode_p.h> -#include <QtQuick/private/qsgdistancefieldglyphnode_p_p.h> -#include <QtQuick/private/qsgatlastexture_p.h> -#include <QtQuick/private/qsgrenderloop_p.h> -#include <QtQuick/private/qsgdefaultlayer_p.h> - #include <QtQuick/private/qsgtexture_p.h> #include <QtQuick/private/qquickpixmapcache_p.h> +#include <QtQuick/private/qsgadaptationlayer_p.h> #include <QGuiApplication> #include <QScreen> -#include <QOpenGLContext> #include <QQuickWindow> -#include <QtGui/qopenglframebufferobject.h> #include <private/qqmlglobal_p.h> @@ -69,8 +55,6 @@ #include <private/qobject_p.h> #include <qmutex.h> -DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) - /* Comments about this class from Gunnar: @@ -114,28 +98,6 @@ Q_LOGGING_CATEGORY(QSG_LOG_TIME_GLYPH, "qt.scenegraph.time.glyph") // Timing inside the renderer base class Q_LOGGING_CATEGORY(QSG_LOG_TIME_RENDERER, "qt.scenegraph.time.renderer") -class QSGContextPrivate : public QObjectPrivate -{ -public: - QSGContextPrivate() - : antialiasingMethod(QSGContext::UndecidedAntialiasing) - , distanceFieldDisabled(qmlDisableDistanceField()) - , distanceFieldAntialiasing(QSGGlyphNode::HighQualitySubPixelAntialiasing) - , distanceFieldAntialiasingDecided(false) - { - } - - ~QSGContextPrivate() - { - } - - QMutex mutex; - QSGContext::AntialiasingMethod antialiasingMethod; - bool distanceFieldDisabled; - QSGDistanceFieldGlyphNode::AntialiasingMode distanceFieldAntialiasing; - bool distanceFieldAntialiasingDecided; -}; - bool qsg_useConsistentTiming() { int use = -1; @@ -274,20 +236,6 @@ public: QSGTexture *texture; }; -namespace QSGMultisampleAntialiasing { - class ImageNode : public QSGDefaultImageNode { - public: - void setAntialiasing(bool) { } - }; - - - class RectangleNode : public QSGDefaultRectangleNode { - public: - void setAntialiasing(bool) { } - }; -} - - /*! \class QSGContext @@ -300,92 +248,16 @@ namespace QSGMultisampleAntialiasing { */ QSGContext::QSGContext(QObject *parent) : - QObject(*(new QSGContextPrivate), parent) + QObject(parent) { - Q_D(QSGContext); - if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QSG_DISTANCEFIELD_ANTIALIASING"))) { - const QByteArray mode = qgetenv("QSG_DISTANCEFIELD_ANTIALIASING"); - d->distanceFieldAntialiasingDecided = true; - if (mode == "subpixel") - d->distanceFieldAntialiasing = QSGGlyphNode::HighQualitySubPixelAntialiasing; - else if (mode == "subpixel-lowq") - d->distanceFieldAntialiasing = QSGGlyphNode::LowQualitySubPixelAntialiasing; - else if (mode == "gray") - d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing; - } - - // Adds compatibility with Qt 5.3 and earlier's QSG_RENDER_TIMING - if (qEnvironmentVariableIsSet("QSG_RENDER_TIMING")) { - const_cast<QLoggingCategory &>(QSG_LOG_TIME_GLYPH()).setEnabled(QtDebugMsg, true); - const_cast<QLoggingCategory &>(QSG_LOG_TIME_TEXTURE()).setEnabled(QtDebugMsg, true); - const_cast<QLoggingCategory &>(QSG_LOG_TIME_RENDERER()).setEnabled(QtDebugMsg, true); - const_cast<QLoggingCategory &>(QSG_LOG_TIME_RENDERLOOP()).setEnabled(QtDebugMsg, true); - const_cast<QLoggingCategory &>(QSG_LOG_TIME_COMPILATION()).setEnabled(QtDebugMsg, true); - } } - QSGContext::~QSGContext() { } -QSGRenderContext *QSGContext::createRenderContext() +void QSGContext::renderContextInitialized(QSGRenderContext *) { - return new QSGRenderContext(this); -} - -void QSGContext::renderContextInitialized(QSGRenderContext *renderContext) -{ - Q_D(QSGContext); - - d->mutex.lock(); - if (d->antialiasingMethod == UndecidedAntialiasing) { - if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_ANTIALIASING_METHOD"))) { - const QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD"); - if (aaType == "msaa") - d->antialiasingMethod = MsaaAntialiasing; - else if (aaType == "vertex") - d->antialiasingMethod = VertexAntialiasing; - } - if (d->antialiasingMethod == UndecidedAntialiasing) { - if (renderContext->openglContext()->format().samples() > 0) - d->antialiasingMethod = MsaaAntialiasing; - else - d->antialiasingMethod = VertexAntialiasing; - } - } - - // With OpenGL ES, except for Angle on Windows, use GrayAntialiasing, unless - // some value had been requested explicitly. This could not be decided - // before without a context. Now the context is ready. - if (!d->distanceFieldAntialiasingDecided) { - d->distanceFieldAntialiasingDecided = true; -#ifndef Q_OS_WIN32 - if (renderContext->openglContext()->isOpenGLES()) - d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing; -#endif - } - - static bool dumped = false; - if (!dumped && QSG_LOG_INFO().isDebugEnabled()) { - dumped = true; - QSurfaceFormat format = renderContext->openglContext()->format(); - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - qCDebug(QSG_LOG_INFO) << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize(); - qCDebug(QSG_LOG_INFO) << "Depth Buffer: " << format.depthBufferSize(); - qCDebug(QSG_LOG_INFO) << "Stencil Buffer: " << format.stencilBufferSize(); - qCDebug(QSG_LOG_INFO) << "Samples: " << format.samples(); - qCDebug(QSG_LOG_INFO) << "GL_VENDOR: " << (const char *) funcs->glGetString(GL_VENDOR); - qCDebug(QSG_LOG_INFO) << "GL_RENDERER: " << (const char *) funcs->glGetString(GL_RENDERER); - qCDebug(QSG_LOG_INFO) << "GL_VERSION: " << (const char *) funcs->glGetString(GL_VERSION); - QSet<QByteArray> exts = renderContext->openglContext()->extensions(); - QByteArray all; foreach (const QByteArray &e, exts) all += ' ' + e; - qCDebug(QSG_LOG_INFO) << "GL_EXTENSIONS: " << all.constData(); - qCDebug(QSG_LOG_INFO) << "Max Texture Size: " << renderContext->maxTextureSize(); - qCDebug(QSG_LOG_INFO) << "Debug context: " << format.testOption(QSurfaceFormat::DebugContext); - } - - d->mutex.unlock(); } void QSGContext::renderContextInvalidated(QSGRenderContext *) @@ -405,89 +277,16 @@ QSGRectangleNode *QSGContext::createRectangleNode(const QRectF &rect, const QCol return node; } -/*! - Factory function for scene graph backends of the Rectangle element. - */ -QSGRectangleNode *QSGContext::createRectangleNode() -{ - Q_D(QSGContext); - return d->antialiasingMethod == MsaaAntialiasing - ? new QSGMultisampleAntialiasing::RectangleNode - : new QSGDefaultRectangleNode; -} - -/*! - Factory function for scene graph backends of the Image element. - */ -QSGImageNode *QSGContext::createImageNode() -{ - Q_D(QSGContext); - return d->antialiasingMethod == MsaaAntialiasing - ? new QSGMultisampleAntialiasing::ImageNode - : new QSGDefaultImageNode; -} - -/*! - Factory function for scene graph backends of Painter elements - */ -QSGPainterNode *QSGContext::createPainterNode(QQuickPaintedItem *item) -{ - return new QSGDefaultPainterNode(item); -} /*! - Factory function for scene graph backends of the Text elements; - */ -QSGGlyphNode *QSGContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) -{ - Q_D(QSGContext); - - if (d->distanceFieldDisabled || preferNativeGlyphNode) { - return new QSGDefaultGlyphNode; - } else { - QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(rc); - node->setPreferredAntialiasingMode(d->distanceFieldAntialiasing); - return node; - } -} - -/*! - * Factory function for scene graph backends of the QStyle stylable elements. Returns a - * null pointer if the backend doesn't provide its own node type. - */ -QSGNinePatchNode *QSGContext::createNinePatchNode() -{ - return 0; -} - -/*! - Factory function for scene graph backends of layers. + Creates a new animation driver. */ -QSGLayer *QSGContext::createLayer(QSGRenderContext *renderContext) -{ - return new QSGDefaultLayer(renderContext); -} -QSurfaceFormat QSGContext::defaultSurfaceFormat() const +QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent) { - QSurfaceFormat format = QSurfaceFormat::defaultFormat(); - static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); - static bool useStencil = qEnvironmentVariableIsEmpty("QSG_NO_STENCIL_BUFFER"); - static bool enableDebug = qEnvironmentVariableIsSet("QSG_OPENGL_DEBUG"); - format.setDepthBufferSize(useDepth ? 24 : 0); - format.setStencilBufferSize(useStencil ? 8 : 0); - if (enableDebug) - format.setOption(QSurfaceFormat::DebugContext); - if (QQuickWindow::hasDefaultAlphaBuffer()) - format.setAlphaBufferSize(8); - format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); - return format; + return new QSGAnimationDriver(parent); } -/*! - Returns the minimum supported framebuffer object size. - */ - QSize QSGContext::minimumFBOSize() const { #ifdef Q_OS_MAC @@ -497,52 +296,26 @@ QSize QSGContext::minimumFBOSize() const return QSize(1, 1); } - - -/*! - Sets whether or not the scene graph should use the distance field technique to render text - */ -void QSGContext::setDistanceFieldEnabled(bool enabled) -{ - d_func()->distanceFieldDisabled = !enabled; -} - - -/*! - Returns true if the scene graph uses the distance field technique to render text - */ -bool QSGContext::isDistanceFieldEnabled() const +QSGRenderContext::QSGRenderContext(QSGContext *context) + : m_sg(context) + , m_distanceFieldCacheManager(0) { - return !d_func()->distanceFieldDisabled; } - - -/*! - Creates a new animation driver. - */ - -QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent) +QSGRenderContext::~QSGRenderContext() { - return new QSGAnimationDriver(parent); + invalidate(); } -QSGRenderContext::QSGRenderContext(QSGContext *context) - : m_gl(0) - , m_sg(context) - , m_atlasManager(0) - , m_depthStencilManager(0) - , m_distanceFieldCacheManager(0) - , m_maxTextureSize(0) - , m_brokenIBOs(false) - , m_serializedRender(false) - , m_attachToGLContext(true) +void QSGRenderContext::initialize(void *context) { + Q_UNUSED(context); } -QSGRenderContext::~QSGRenderContext() +void QSGRenderContext::invalidate() { - invalidate(); + m_sg->renderContextInvalidated(this); + emit invalidated(); } void QSGRenderContext::endSync() @@ -551,49 +324,14 @@ void QSGRenderContext::endSync() m_texturesToDelete.clear(); } -static QBasicMutex qsg_framerender_mutex; - -void QSGRenderContext::renderNextFrame(QSGRenderer *renderer, GLuint fboId) -{ - if (m_serializedRender) - qsg_framerender_mutex.lock(); - - renderer->renderScene(fboId); - - if (m_serializedRender) - qsg_framerender_mutex.unlock(); - -} - /*! Factory function for scene graph backends of the distance-field glyph cache. */ -QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRawFont &font) -{ - if (!m_distanceFieldCacheManager) - m_distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager; - - QSGDistanceFieldGlyphCache *cache = m_distanceFieldCacheManager->cache(font); - if (!cache) { - cache = new QSGDefaultDistanceFieldGlyphCache(m_distanceFieldCacheManager, openglContext(), font); - m_distanceFieldCacheManager->insertCache(font, cache); - } - - return cache; -} - -void QSGRenderContext::setAttachToGLContext(bool attach) +QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRawFont &) { - Q_ASSERT(!isValid()); - m_attachToGLContext = attach; + return nullptr; } -#define QSG_RENDERCONTEXT_PROPERTY "_q_sgrendercontext" - -QSGRenderContext *QSGRenderContext::from(QOpenGLContext *context) -{ - return qobject_cast<QSGRenderContext *>(context->property(QSG_RENDERCONTEXT_PROPERTY).value<QObject *>()); -} void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine) { @@ -602,178 +340,18 @@ void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine) } /*! - Initializes the scene graph render context with the GL context \a context. This also - emits the ready() signal so that the QML graph can start building scene graph nodes. - */ -void QSGRenderContext::initialize(QOpenGLContext *context) -{ - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); - - // Sanity check the surface format, in case it was overridden by the application - QSurfaceFormat requested = m_sg->defaultSurfaceFormat(); - QSurfaceFormat actual = context->format(); - if (requested.depthBufferSize() > 0 && actual.depthBufferSize() <= 0) - qWarning("QSGContext::initialize: depth buffer support missing, expect rendering errors"); - if (requested.stencilBufferSize() > 0 && actual.stencilBufferSize() <= 0) - qWarning("QSGContext::initialize: stencil buffer support missing, expect rendering errors"); - - if (!m_atlasManager) - m_atlasManager = new QSGAtlasTexture::Manager(); - - Q_ASSERT_X(!m_gl, "QSGRenderContext::initialize", "already initialized!"); - m_gl = context; - if (m_attachToGLContext) { - Q_ASSERT(!context->property(QSG_RENDERCONTEXT_PROPERTY).isValid()); - context->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant::fromValue(this)); - } - m_sg->renderContextInitialized(this); - -#ifdef Q_OS_LINUX - const char *vendor = (const char *) funcs->glGetString(GL_VENDOR); - if (strstr(vendor, "nouveau")) - m_brokenIBOs = true; - const char *renderer = (const char *) funcs->glGetString(GL_RENDERER); - if (strstr(renderer, "llvmpipe")) - m_serializedRender = true; - if (strstr(vendor, "Hisilicon Technologies") && strstr(renderer, "Immersion.16")) - m_brokenIBOs = true; -#endif - - emit initialized(); -} - -void QSGRenderContext::invalidate() -{ - if (!m_gl) - return; - - qDeleteAll(m_texturesToDelete); - m_texturesToDelete.clear(); - - qDeleteAll(m_textures); - m_textures.clear(); - - /* The cleanup of the atlas textures is a bit intriguing. - As part of the cleanup in the threaded render loop, we - do: - 1. call this function - 2. call QCoreApp::sendPostedEvents() to immediately process - any pending deferred deletes. - 3. delete the GL context. - - As textures need the atlas manager while cleaning up, the - manager needs to be cleaned up after the textures, so - we post a deleteLater here at the very bottom so it gets - deferred deleted last. - - Another alternative would be to use a QPointer in - QSGAtlasTexture::Texture, but this seemed simpler. - */ - m_atlasManager->invalidate(); - m_atlasManager->deleteLater(); - m_atlasManager = 0; - - // The following piece of code will read/write to the font engine's caches, - // potentially from different threads. However, this is safe because this - // code is only called from QQuickWindow's shutdown which is called - // only when the GUI is blocked, and multiple threads will call it in - // sequence. (see qsgdefaultglyphnode_p.cpp's init()) - for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(), - end = m_fontEnginesToClean.constEnd(); it != end; ++it) { - (*it)->clearGlyphCache(m_gl); - if (!(*it)->ref.deref()) - delete *it; - } - m_fontEnginesToClean.clear(); - - delete m_depthStencilManager; - m_depthStencilManager = 0; - - delete m_distanceFieldCacheManager; - m_distanceFieldCacheManager = 0; - - if (m_gl->property(QSG_RENDERCONTEXT_PROPERTY) == QVariant::fromValue(this)) - m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant()); - m_gl = 0; - - m_sg->renderContextInvalidated(this); - emit invalidated(); -} - -/*! - Returns a shared pointer to a depth stencil buffer that can be used with \a fbo. - */ -QSharedPointer<QSGDepthStencilBuffer> QSGRenderContext::depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo) -{ - if (!m_gl) - return QSharedPointer<QSGDepthStencilBuffer>(); - QSGDepthStencilBufferManager *manager = depthStencilBufferManager(); - QSGDepthStencilBuffer::Format format; - format.size = fbo->size(); - format.samples = fbo->format().samples(); - format.attachments = QSGDepthStencilBuffer::DepthAttachment | QSGDepthStencilBuffer::StencilAttachment; - QSharedPointer<QSGDepthStencilBuffer> buffer = manager->bufferForFormat(format); - if (buffer.isNull()) { - buffer = QSharedPointer<QSGDepthStencilBuffer>(new QSGDefaultDepthStencilBuffer(m_gl, format)); - manager->insertBuffer(buffer); - } - return buffer; -} - -/*! - Returns a pointer to the context's depth/stencil buffer manager. This is useful for custom - implementations of \l depthStencilBufferForFbo(). - */ -QSGDepthStencilBufferManager *QSGRenderContext::depthStencilBufferManager() -{ - if (!m_gl) - return 0; - if (!m_depthStencilManager) - m_depthStencilManager = new QSGDepthStencilBufferManager(m_gl); - return m_depthStencilManager; -} - - -/*! Factory function for texture objects. If \a image is a valid image, the QSGTexture::setImage function will be called with \a image as argument. */ -QSGTexture *QSGRenderContext::createTexture(const QImage &image, uint flags) const -{ - bool atlas = flags & CreateTexture_Atlas; - bool mipmap = flags & CreateTexture_Mipmap; - bool alpha = flags & CreateTexture_Alpha; - - // The atlas implementation is only supported from the render thread and - // does not support mipmaps. - if (!mipmap && atlas && openglContext() && QThread::currentThread() == openglContext()->thread()) { - QSGTexture *t = m_atlasManager->create(image, alpha); - if (t) - return t; - } - - QSGPlainTexture *texture = new QSGPlainTexture(); - texture->setImage(image); - if (texture->hasAlphaChannel() && !alpha) - texture->setHasAlphaChannel(false); - - return texture; -} - /*! Factory function for the scene graph renderers. The renderers are used for the toplevel renderer and once for every QQuickShaderEffectSource used in the QML scene. */ -QSGRenderer *QSGRenderContext::createRenderer() -{ - return new QSGBatchRenderer::Renderer(this); -} QSGTexture *QSGRenderContext::textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window) { @@ -803,41 +381,6 @@ void QSGRenderContext::textureFactoryDestroyed(QObject *o) m_mutex.unlock(); } -/*! - Compile \a shader, optionally using \a vertexCode and \a fragmentCode as - replacement for the source code supplied by \a shader. - - If \a vertexCode or \a fragmentCode is supplied, the caller is responsible - for setting up attribute bindings. - - \a material is supplied in case the implementation needs to take the - material flags into account. - */ - -void QSGRenderContext::compile(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode, const char *fragmentCode) -{ - Q_UNUSED(material); - if (vertexCode || fragmentCode) { - Q_ASSERT_X((material->flags() & QSGMaterial::CustomCompileStep) == 0, - "QSGRenderContext::compile()", - "materials with custom compile step cannot have custom vertex/fragment code"); - QOpenGLShaderProgram *p = shader->program(); - p->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexCode ? vertexCode : shader->vertexShader()); - p->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader()); - p->link(); - if (!p->isLinked()) - qWarning() << "shader compilation failed:" << endl << p->log(); - } else { - shader->compile(); - } -} - -void QSGRenderContext::initialize(QSGMaterialShader *shader) -{ - shader->program()->bind(); - shader->initialize(); -} - #include "qsgcontext.moc" QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 38d0cdaccc..3893560142 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -53,6 +53,7 @@ #include <QtCore/QObject> #include <QtCore/qabstractanimation.h> +#include <QtCore/QMutex> #include <QtGui/QImage> #include <QtGui/QSurfaceFormat> @@ -61,14 +62,9 @@ #include <private/qrawfont_p.h> #include <QtQuick/qsgnode.h> -#include <QtQuick/private/qsgdepthstencilbuffer_p.h> QT_BEGIN_NAMESPACE -namespace QSGAtlasTexture { - class Manager; -} - class QSGContextPrivate; class QSGRectangleNode; class QSGImageNode; @@ -80,13 +76,8 @@ class QSGDistanceFieldGlyphCache; class QQuickWindow; class QSGTexture; class QSGMaterial; -class QSGMaterialShader; class QSGRenderLoop; class QSGLayer; - -class QOpenGLContext; -class QOpenGLFramebufferObject; - class QQuickTextureFactory; class QSGDistanceFieldGlyphCacheManager; class QSGContext; @@ -112,39 +103,24 @@ public: }; QSGRenderContext(QSGContext *context); - ~QSGRenderContext(); + virtual ~QSGRenderContext(); - QOpenGLContext *openglContext() const { return m_gl; } QSGContext *sceneGraphContext() const { return m_sg; } - virtual bool isValid() const { return m_gl; } + virtual bool isValid() const { return true; } - virtual void initialize(QOpenGLContext *context); + virtual void initialize(void *context); virtual void invalidate(); - - virtual void renderNextFrame(QSGRenderer *renderer, GLuint fboId); + virtual void renderNextFrame(QSGRenderer *renderer, uint fboId) = 0; virtual void endSync(); - virtual QSharedPointer<QSGDepthStencilBuffer> depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo); - QSGDepthStencilBufferManager *depthStencilBufferManager(); - virtual QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font); QSGTexture *textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window); - virtual QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const; - - virtual QSGRenderer *createRenderer(); + virtual QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const = 0; + virtual QSGRenderer *createRenderer() = 0; - virtual void compile(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = 0, const char *fragmentCode = 0); - virtual void initialize(QSGMaterialShader *shader); - - void setAttachToGLContext(bool attach); void registerFontengineForCleanup(QFontEngine *engine); - static QSGRenderContext *from(QOpenGLContext *context); - - bool hasBrokenIndexBufferObjects() const { return m_brokenIBOs; } - int maxTextureSize() const { return m_maxTextureSize; } - Q_SIGNALS: void initialized(); void invalidated(); @@ -153,29 +129,20 @@ public Q_SLOTS: void textureFactoryDestroyed(QObject *o); protected: - QOpenGLContext *m_gl; QSGContext *m_sg; QMutex m_mutex; QHash<QQuickTextureFactory *, QSGTexture *> m_textures; QSet<QSGTexture *> m_texturesToDelete; - QSGAtlasTexture::Manager *m_atlasManager; - - QSGDepthStencilBufferManager *m_depthStencilManager; QSGDistanceFieldGlyphCacheManager *m_distanceFieldCacheManager; QSet<QFontEngine *> m_fontEnginesToClean; - int m_maxTextureSize; - bool m_brokenIBOs; - bool m_serializedRender; - bool m_attachToGLContext; }; class Q_QUICK_PRIVATE_EXPORT QSGContext : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QSGContext) public: enum AntialiasingMethod { @@ -185,26 +152,23 @@ public: }; explicit QSGContext(QObject *parent = 0); - ~QSGContext(); + virtual ~QSGContext(); virtual void renderContextInitialized(QSGRenderContext *renderContext); virtual void renderContextInvalidated(QSGRenderContext *renderContext); - virtual QSGRenderContext *createRenderContext(); + virtual QSGRenderContext *createRenderContext() = 0; QSGRectangleNode *createRectangleNode(const QRectF &rect, const QColor &c); - virtual QSGRectangleNode *createRectangleNode(); - virtual QSGImageNode *createImageNode(); - virtual QSGPainterNode *createPainterNode(QQuickPaintedItem *item); - virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode); - virtual QSGNinePatchNode *createNinePatchNode(); - virtual QSGLayer *createLayer(QSGRenderContext *renderContext); + virtual QSGRectangleNode *createRectangleNode() = 0; + virtual QSGImageNode *createImageNode() = 0; + virtual QSGPainterNode *createPainterNode(QQuickPaintedItem *item) = 0; + virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) = 0; + virtual QSGNinePatchNode *createNinePatchNode() = 0; + virtual QSGLayer *createLayer(QSGRenderContext *renderContext) = 0; virtual QAnimationDriver *createAnimationDriver(QObject *parent); virtual QSize minimumFBOSize() const; - virtual QSurfaceFormat defaultSurfaceFormat() const; - - void setDistanceFieldEnabled(bool enabled); - bool isDistanceFieldEnabled() const; + virtual QSurfaceFormat defaultSurfaceFormat() const = 0; static QSGContext *createDefaultContext(); static QQuickTextureFactory *createTextureFactoryFromImage(const QImage &image); diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp index cf12918e3e..1605212c76 100644 --- a/src/quick/scenegraph/qsgcontextplugin.cpp +++ b/src/quick/scenegraph/qsgcontextplugin.cpp @@ -44,11 +44,13 @@ #include <QtCore/qlibraryinfo.h> // Built-in adaptations -#include <QtQuick/private/qsgdummyadaptation_p.h> #include <QtQuick/private/qsgsoftwareadaptation_p.h> #ifdef QSG_D3D12 #include <QtQuick/private/qsgd3d12adaptation_p.h> #endif +#ifndef QT_NO_OPENGL +#include <QtQuick/private/qsgdefaultcontext_p.h> +#endif QT_BEGIN_NAMESPACE @@ -84,7 +86,6 @@ QSGAdaptionBackendData::QSGAdaptionBackendData() , factory(0) { // Fill in the table with the built-in adaptations. - builtIns.append(new QSGDummyAdaptation); builtIns.append(new QSGSoftwareAdaptation); #ifdef QSG_D3D12 builtIns.append(new QSGD3D12Adaptation); @@ -102,6 +103,7 @@ QSGAdaptionBackendData *contextFactory() const QStringList args = QGuiApplication::arguments(); QString requestedBackend; + for (int index = 0; index < args.count(); ++index) { if (args.at(index).startsWith(QLatin1String("--device="))) { requestedBackend = args.at(index).mid(9); @@ -118,6 +120,13 @@ QSGAdaptionBackendData *contextFactory() if (requestedBackend.isEmpty() && qEnvironmentVariableIsSet("QT_QUICK_BACKEND")) requestedBackend = QString::fromLocal8Bit(qgetenv("QT_QUICK_BACKEND")); +#ifdef QT_NO_OPENGL + // If this is a build without OpenGL, and no backend has been set + // default to the software renderer + if (requestedBackend.isEmpty()) + requestedBackend = QString::fromLocal8Bit("software"); +#endif + if (!requestedBackend.isEmpty()) { #ifndef QT_NO_DEBUG qCDebug(QSG_LOG_INFO) << "Loading backend" << requestedBackend; @@ -167,7 +176,11 @@ QSGContext *QSGContext::createDefaultContext() QSGAdaptionBackendData *backendData = contextFactory(); if (backendData->factory) return backendData->factory->create(backendData->name); - return new QSGContext(); +#ifndef QT_NO_OPENGL + return new QSGDefaultContext(); +#else + return nullptr; +#endif } diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp new file mode 100644 index 0000000000..f969359e7c --- /dev/null +++ b/src/quick/scenegraph/qsgdefaultcontext.cpp @@ -0,0 +1,243 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgdefaultcontext_p.h" + +#include <QtQuick/private/qsgdistancefieldutil_p.h> +#include <QtQuick/private/qsgdefaultrectanglenode_p.h> +#include <QtQuick/private/qsgdefaultimagenode_p.h> +#include <QtQuick/private/qsgdefaultpainternode_p.h> +#include <QtQuick/private/qsgdefaultglyphnode_p.h> +#include <QtQuick/private/qsgdistancefieldglyphnode_p.h> +#include <QtQuick/private/qsgdistancefieldglyphnode_p_p.h> +#include <QtQuick/private/qsgrenderloop_p.h> +#include <QtQuick/private/qsgdefaultlayer_p.h> +#include <QtQuick/private/qsgdefaultrendercontext_p.h> + +#include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFramebufferObject> + +#include <QtQuick/QQuickWindow> + +#include <private/qqmlglobal_p.h> + +QT_BEGIN_NAMESPACE + +namespace QSGMultisampleAntialiasing { + class ImageNode : public QSGDefaultImageNode { + public: + void setAntialiasing(bool) { } + }; + + + class RectangleNode : public QSGDefaultRectangleNode { + public: + void setAntialiasing(bool) { } + }; +} + +DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) + +QSGDefaultContext::QSGDefaultContext(QObject *parent) + : QSGContext (parent) + , m_antialiasingMethod(QSGContext::UndecidedAntialiasing) + , m_distanceFieldDisabled(qmlDisableDistanceField()) + , m_distanceFieldAntialiasing(QSGGlyphNode::HighQualitySubPixelAntialiasing) + , m_distanceFieldAntialiasingDecided(false) +{ + if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QSG_DISTANCEFIELD_ANTIALIASING"))) { + const QByteArray mode = qgetenv("QSG_DISTANCEFIELD_ANTIALIASING"); + m_distanceFieldAntialiasingDecided = true; + if (mode == "subpixel") + m_distanceFieldAntialiasing = QSGGlyphNode::HighQualitySubPixelAntialiasing; + else if (mode == "subpixel-lowq") + m_distanceFieldAntialiasing = QSGGlyphNode::LowQualitySubPixelAntialiasing; + else if (mode == "gray") + m_distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing; + } + + // Adds compatibility with Qt 5.3 and earlier's QSG_RENDER_TIMING + if (qEnvironmentVariableIsSet("QSG_RENDER_TIMING")) { + const_cast<QLoggingCategory &>(QSG_LOG_TIME_GLYPH()).setEnabled(QtDebugMsg, true); + const_cast<QLoggingCategory &>(QSG_LOG_TIME_TEXTURE()).setEnabled(QtDebugMsg, true); + const_cast<QLoggingCategory &>(QSG_LOG_TIME_RENDERER()).setEnabled(QtDebugMsg, true); + const_cast<QLoggingCategory &>(QSG_LOG_TIME_RENDERLOOP()).setEnabled(QtDebugMsg, true); + const_cast<QLoggingCategory &>(QSG_LOG_TIME_COMPILATION()).setEnabled(QtDebugMsg, true); + } +} + +QSGDefaultContext::~QSGDefaultContext() +{ + +} + +void QSGDefaultContext::renderContextInitialized(QSGRenderContext *renderContext) +{ + m_mutex.lock(); + + auto openglRenderContext = static_cast<const QSGDefaultRenderContext *>(renderContext); + if (m_antialiasingMethod == UndecidedAntialiasing) { + if (Q_UNLIKELY(qEnvironmentVariableIsSet("QSG_ANTIALIASING_METHOD"))) { + const QByteArray aaType = qgetenv("QSG_ANTIALIASING_METHOD"); + if (aaType == "msaa") + m_antialiasingMethod = MsaaAntialiasing; + else if (aaType == "vertex") + m_antialiasingMethod = VertexAntialiasing; + } + if (m_antialiasingMethod == UndecidedAntialiasing) { + if (openglRenderContext->openglContext()->format().samples() > 0) + m_antialiasingMethod = MsaaAntialiasing; + else + m_antialiasingMethod = VertexAntialiasing; + } + } + + // With OpenGL ES, except for Angle on Windows, use GrayAntialiasing, unless + // some value had been requested explicitly. This could not be decided + // before without a context. Now the context is ready. + if (!m_distanceFieldAntialiasingDecided) { + m_distanceFieldAntialiasingDecided = true; +#ifndef Q_OS_WIN32 + if (openglRenderContext->openglContext()->isOpenGLES()) + m_distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing; +#endif + } + + static bool dumped = false; + if (!dumped && QSG_LOG_INFO().isDebugEnabled()) { + dumped = true; + QSurfaceFormat format = openglRenderContext->openglContext()->format(); + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + qCDebug(QSG_LOG_INFO) << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize(); + qCDebug(QSG_LOG_INFO) << "Depth Buffer: " << format.depthBufferSize(); + qCDebug(QSG_LOG_INFO) << "Stencil Buffer: " << format.stencilBufferSize(); + qCDebug(QSG_LOG_INFO) << "Samples: " << format.samples(); + qCDebug(QSG_LOG_INFO) << "GL_VENDOR: " << (const char *) funcs->glGetString(GL_VENDOR); + qCDebug(QSG_LOG_INFO) << "GL_RENDERER: " << (const char *) funcs->glGetString(GL_RENDERER); + qCDebug(QSG_LOG_INFO) << "GL_VERSION: " << (const char *) funcs->glGetString(GL_VERSION); + QSet<QByteArray> exts = openglRenderContext->openglContext()->extensions(); + QByteArray all; foreach (const QByteArray &e, exts) all += ' ' + e; + qCDebug(QSG_LOG_INFO) << "GL_EXTENSIONS: " << all.constData(); + qCDebug(QSG_LOG_INFO) << "Max Texture Size: " << openglRenderContext->maxTextureSize(); + qCDebug(QSG_LOG_INFO) << "Debug context: " << format.testOption(QSurfaceFormat::DebugContext); + } + + m_mutex.unlock(); +} + +void QSGDefaultContext::renderContextInvalidated(QSGRenderContext *) +{ +} + +QSGRenderContext *QSGDefaultContext::createRenderContext() +{ + return new QSGDefaultRenderContext(this); +} + +QSGRectangleNode *QSGDefaultContext::createRectangleNode() +{ + return m_antialiasingMethod == MsaaAntialiasing + ? new QSGMultisampleAntialiasing::RectangleNode + : new QSGDefaultRectangleNode; +} + +QSGImageNode *QSGDefaultContext::createImageNode() +{ + return m_antialiasingMethod == MsaaAntialiasing + ? new QSGMultisampleAntialiasing::ImageNode + : new QSGDefaultImageNode; +} + +QSGPainterNode *QSGDefaultContext::createPainterNode(QQuickPaintedItem *item) +{ + return new QSGDefaultPainterNode(item); +} + +QSGGlyphNode *QSGDefaultContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) +{ + if (m_distanceFieldDisabled || preferNativeGlyphNode) { + return new QSGDefaultGlyphNode; + } else { + QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(rc); + node->setPreferredAntialiasingMode(m_distanceFieldAntialiasing); + return node; + } +} + +/*! + * Factory function for scene graph backends of the QStyle stylable elements. Returns a + * null pointer if the backend doesn't provide its own node type. + */ +QSGNinePatchNode *QSGDefaultContext::createNinePatchNode() +{ + return nullptr; +} + +QSGLayer *QSGDefaultContext::createLayer(QSGRenderContext *renderContext) +{ + return new QSGDefaultLayer(renderContext); +} + +QSurfaceFormat QSGDefaultContext::defaultSurfaceFormat() const +{ + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); + static bool useDepth = qEnvironmentVariableIsEmpty("QSG_NO_DEPTH_BUFFER"); + static bool useStencil = qEnvironmentVariableIsEmpty("QSG_NO_STENCIL_BUFFER"); + static bool enableDebug = qEnvironmentVariableIsSet("QSG_OPENGL_DEBUG"); + format.setDepthBufferSize(useDepth ? 24 : 0); + format.setStencilBufferSize(useStencil ? 8 : 0); + if (enableDebug) + format.setOption(QSurfaceFormat::DebugContext); + if (QQuickWindow::hasDefaultAlphaBuffer()) + format.setAlphaBufferSize(8); + format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); + return format; +} + +void QSGDefaultContext::setDistanceFieldEnabled(bool enabled) +{ + m_distanceFieldDisabled = !enabled; +} + +bool QSGDefaultContext::isDistanceFieldEnabled() const +{ + return !m_distanceFieldDisabled; +} + +QT_END_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation_p.h b/src/quick/scenegraph/qsgdefaultcontext_p.h index aa0599de79..0569b7c321 100644 --- a/src/quick/scenegraph/adaptations/dummy/qsgdummyadaptation_p.h +++ b/src/quick/scenegraph/qsgdefaultcontext_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QSGDUMMYADAPTATION_P_H -#define QSGDUMMYADAPTATION_P_H +#ifndef QSGDEFAULTCONTEXT_H +#define QSGDEFAULTCONTEXT_H // // W A R N I N G @@ -51,26 +51,39 @@ // We mean it. // -#include <private/qsgcontext_p.h> -#include <private/qsgcontextplugin_p.h> +#include <QtQuick/private/qsgcontext_p.h> +#include <QtQuick/private/qsgdistancefieldglyphnode_p.h> QT_BEGIN_NAMESPACE -class QSGDummyContext; - -class QSGDummyAdaptation : public QSGContextPlugin +class QSGDefaultContext : public QSGContext { public: - QSGDummyAdaptation(QObject *parent = 0); + QSGDefaultContext(QObject *parent = 0); + ~QSGDefaultContext(); + + void renderContextInitialized(QSGRenderContext *renderContext) override; + void renderContextInvalidated(QSGRenderContext *) override; + QSGRenderContext *createRenderContext() override; + QSGRectangleNode *createRectangleNode() override; + QSGImageNode *createImageNode() override; + QSGPainterNode *createPainterNode(QQuickPaintedItem *item) override; + QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override; + QSGNinePatchNode *createNinePatchNode() override; + QSGLayer *createLayer(QSGRenderContext *renderContext) override; + QSurfaceFormat defaultSurfaceFormat() const override; - QStringList keys() const override; - QSGContext *create(const QString &key) const override; - QSGRenderLoop *createWindowManager() override; + void setDistanceFieldEnabled(bool enabled); + bool isDistanceFieldEnabled() const; private: - static QSGDummyContext *contextInstance; + QMutex m_mutex; + QSGContext::AntialiasingMethod m_antialiasingMethod; + bool m_distanceFieldDisabled; + QSGDistanceFieldGlyphNode::AntialiasingMode m_distanceFieldAntialiasing; + bool m_distanceFieldAntialiasingDecided; }; QT_END_NAMESPACE -#endif // QSGDUMMYADAPTATION_P_H +#endif // QSGDEFAULTCONTEXT_H diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 78b803df83..d8552e622d 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -49,6 +49,7 @@ #include <QtQuick/qquickwindow.h> #include <QtQuick/private/qsgtexture_p.h> +#include <QtQuick/private/qsgdefaultrendercontext_p.h> #include <private/qrawfont_p.h> #include <QtCore/qmath.h> @@ -427,7 +428,7 @@ void QSGTextMaskMaterial::init(QFontEngine::GlyphFormat glyphFormat) if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) { m_glyphCache = new QOpenGLTextureGlyphCache(glyphFormat, glyphCacheTransform); fontEngine->setGlyphCache(ctx, m_glyphCache.data()); - QSGRenderContext *sg = QSGRenderContext::from(ctx); + auto sg = QSGDefaultRenderContext::from(ctx); Q_ASSERT(sg); sg->registerFontengineForCleanup(fontEngine); } diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp index 2f1c1d454c..ad5b57ff83 100644 --- a/src/quick/scenegraph/qsgdefaultlayer.cpp +++ b/src/quick/scenegraph/qsgdefaultlayer.cpp @@ -40,8 +40,12 @@ #include <private/qqmlglobal_p.h> #include <private/qsgrenderer_p.h> +#include <private/qsgdefaultrendercontext_p.h> -#include <QOpenGLFramebufferObject> +#include <QtGui/QOpenGLFramebufferObject> +#include <QtGui/QOpenGLFunctions> + +#include <QtQuick/private/qsgdepthstencilbuffer_p.h> #ifdef QSG_DEBUG_FBO_OVERLAY DEFINE_BOOL_CONFIG_OPTION(qmlFboOverlay, QML_FBO_OVERLAY) @@ -95,7 +99,6 @@ QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context) #ifdef QSG_DEBUG_FBO_OVERLAY , m_debugOverlay(0) #endif - , m_context(context) , m_mipmap(false) , m_live(true) , m_recursive(false) @@ -106,6 +109,7 @@ QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context) , m_mirrorHorizontal(false) , m_mirrorVertical(true) { + m_context = static_cast<QSGDefaultRenderContext *>(context); } QSGDefaultLayer::~QSGDefaultLayer() diff --git a/src/quick/scenegraph/qsgdefaultlayer_p.h b/src/quick/scenegraph/qsgdefaultlayer_p.h index 8bb565f845..ae39994096 100644 --- a/src/quick/scenegraph/qsgdefaultlayer_p.h +++ b/src/quick/scenegraph/qsgdefaultlayer_p.h @@ -54,8 +54,14 @@ #include <private/qsgcontext_p.h> #include <qsgsimplerectnode.h> +QT_BEGIN_NAMESPACE + #define QSG_DEBUG_FBO_OVERLAY +class QOpenGLFramebufferObject; +class QSGDepthStencilBuffer; +class QSGDefaultRenderContext; + class Q_QUICK_PRIVATE_EXPORT QSGDefaultLayer : public QSGLayer { Q_OBJECT @@ -131,7 +137,7 @@ private: QSGSimpleRectNode *m_debugOverlay; #endif - QSGRenderContext *m_context; + QSGDefaultRenderContext *m_context; uint m_mipmap : 1; uint m_live : 1; @@ -144,4 +150,6 @@ private: uint m_mirrorVertical : 1; }; +QT_END_NAMESPACE + #endif // QSGDEFAULTLAYER_P_H diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp new file mode 100644 index 0000000000..92e7f983a0 --- /dev/null +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -0,0 +1,302 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgdefaultrendercontext_p.h" + +#include <QtGui/QOpenGLFramebufferObject> + +#include <QtQuick/private/qsgbatchrenderer_p.h> +#include <QtQuick/private/qsgrenderer_p.h> +#include <QtQuick/private/qsgatlastexture_p.h> +#include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h> +#include <QtQuick/private/qsgdistancefieldutil_p.h> + +QT_BEGIN_NAMESPACE + +#define QSG_RENDERCONTEXT_PROPERTY "_q_sgrendercontext" + +QSGDefaultRenderContext::QSGDefaultRenderContext(QSGContext *context) + : QSGRenderContext(context) + , m_gl(nullptr) + , m_depthStencilManager(nullptr) + , m_maxTextureSize(0) + , m_brokenIBOs(false) + , m_serializedRender(false) + , m_attachToGLContext(true) + , m_atlasManager(nullptr) +{ + +} + +/*! + Initializes the scene graph render context with the GL context \a context. This also + emits the ready() signal so that the QML graph can start building scene graph nodes. + */ +void QSGDefaultRenderContext::initialize(void *context) +{ + QOpenGLContext *openglContext = static_cast<QOpenGLContext *>(context); + + QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); + + // Sanity check the surface format, in case it was overridden by the application + QSurfaceFormat requested = m_sg->defaultSurfaceFormat(); + QSurfaceFormat actual = openglContext->format(); + if (requested.depthBufferSize() > 0 && actual.depthBufferSize() <= 0) + qWarning("QSGContext::initialize: depth buffer support missing, expect rendering errors"); + if (requested.stencilBufferSize() > 0 && actual.stencilBufferSize() <= 0) + qWarning("QSGContext::initialize: stencil buffer support missing, expect rendering errors"); + + if (!m_atlasManager) + m_atlasManager = new QSGAtlasTexture::Manager(); + + Q_ASSERT_X(!m_gl, "QSGRenderContext::initialize", "already initialized!"); + m_gl = openglContext; + if (m_attachToGLContext) { + Q_ASSERT(!openglContext->property(QSG_RENDERCONTEXT_PROPERTY).isValid()); + openglContext->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant::fromValue(this)); + } + m_sg->renderContextInitialized(this); + +#ifdef Q_OS_LINUX + const char *vendor = (const char *) funcs->glGetString(GL_VENDOR); + if (strstr(vendor, "nouveau")) + m_brokenIBOs = true; + const char *renderer = (const char *) funcs->glGetString(GL_RENDERER); + if (strstr(renderer, "llvmpipe")) + m_serializedRender = true; + if (strstr(vendor, "Hisilicon Technologies") && strstr(renderer, "Immersion.16")) + m_brokenIBOs = true; +#endif + + emit initialized(); +} + + +void QSGDefaultRenderContext::invalidate() +{ + if (!m_gl) + return; + + qDeleteAll(m_texturesToDelete); + m_texturesToDelete.clear(); + + qDeleteAll(m_textures); + m_textures.clear(); + + /* The cleanup of the atlas textures is a bit intriguing. + As part of the cleanup in the threaded render loop, we + do: + 1. call this function + 2. call QCoreApp::sendPostedEvents() to immediately process + any pending deferred deletes. + 3. delete the GL context. + + As textures need the atlas manager while cleaning up, the + manager needs to be cleaned up after the textures, so + we post a deleteLater here at the very bottom so it gets + deferred deleted last. + + Another alternative would be to use a QPointer in + QSGAtlasTexture::Texture, but this seemed simpler. + */ + m_atlasManager->invalidate(); + m_atlasManager->deleteLater(); + m_atlasManager = nullptr; + + // The following piece of code will read/write to the font engine's caches, + // potentially from different threads. However, this is safe because this + // code is only called from QQuickWindow's shutdown which is called + // only when the GUI is blocked, and multiple threads will call it in + // sequence. (see qsgdefaultglyphnode_p.cpp's init()) + for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(), + end = m_fontEnginesToClean.constEnd(); it != end; ++it) { + (*it)->clearGlyphCache(m_gl); + if (!(*it)->ref.deref()) + delete *it; + } + m_fontEnginesToClean.clear(); + + delete m_depthStencilManager; + m_depthStencilManager = 0; + + delete m_distanceFieldCacheManager; + m_distanceFieldCacheManager = 0; + + if (m_gl->property(QSG_RENDERCONTEXT_PROPERTY) == QVariant::fromValue(this)) + m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant()); + m_gl = 0; + + QSGRenderContext::invalidate(); +} + +static QBasicMutex qsg_framerender_mutex; + +void QSGDefaultRenderContext::renderNextFrame(QSGRenderer *renderer, uint fboId) +{ + if (m_serializedRender) + qsg_framerender_mutex.lock(); + + renderer->renderScene(fboId); + + if (m_serializedRender) + qsg_framerender_mutex.unlock(); +} + +/*! + Returns a shared pointer to a depth stencil buffer that can be used with \a fbo. +*/ +QSharedPointer<QSGDepthStencilBuffer> QSGDefaultRenderContext::depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo) +{ + if (!m_gl) + return QSharedPointer<QSGDepthStencilBuffer>(); + QSGDepthStencilBufferManager *manager = depthStencilBufferManager(); + QSGDepthStencilBuffer::Format format; + format.size = fbo->size(); + format.samples = fbo->format().samples(); + format.attachments = QSGDepthStencilBuffer::DepthAttachment | QSGDepthStencilBuffer::StencilAttachment; + QSharedPointer<QSGDepthStencilBuffer> buffer = manager->bufferForFormat(format); + if (buffer.isNull()) { + buffer = QSharedPointer<QSGDepthStencilBuffer>(new QSGDefaultDepthStencilBuffer(m_gl, format)); + manager->insertBuffer(buffer); + } + return buffer; +} + +/*! + Returns a pointer to the context's depth/stencil buffer manager. This is useful for custom + implementations of \l depthStencilBufferForFbo(). +*/ +QSGDepthStencilBufferManager *QSGDefaultRenderContext::depthStencilBufferManager() +{ + if (!m_gl) + return 0; + if (!m_depthStencilManager) + m_depthStencilManager = new QSGDepthStencilBufferManager(m_gl); + return m_depthStencilManager; +} + +QSGTexture *QSGDefaultRenderContext::createTexture(const QImage &image, uint flags) const +{ + bool atlas = flags & CreateTexture_Atlas; + bool mipmap = flags & CreateTexture_Mipmap; + bool alpha = flags & CreateTexture_Alpha; + + // The atlas implementation is only supported from the render thread and + // does not support mipmaps. + if (!mipmap && atlas && openglContext() && QThread::currentThread() == openglContext()->thread()) { + QSGTexture *t = m_atlasManager->create(image, alpha); + if (t) + return t; + } + + QSGPlainTexture *texture = new QSGPlainTexture(); + texture->setImage(image); + if (texture->hasAlphaChannel() && !alpha) + texture->setHasAlphaChannel(false); + + return texture; +} + +QSGRenderer *QSGDefaultRenderContext::createRenderer() +{ + return new QSGBatchRenderer::Renderer(this); +} + +/*! + Compile \a shader, optionally using \a vertexCode and \a fragmentCode as + replacement for the source code supplied by \a shader. + + If \a vertexCode or \a fragmentCode is supplied, the caller is responsible + for setting up attribute bindings. + + \a material is supplied in case the implementation needs to take the + material flags into account. + */ +void QSGDefaultRenderContext::compileShader(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode, const char *fragmentCode) +{ + Q_UNUSED(material); + if (vertexCode || fragmentCode) { + Q_ASSERT_X((material->flags() & QSGMaterial::CustomCompileStep) == 0, + "QSGRenderContext::compile()", + "materials with custom compile step cannot have custom vertex/fragment code"); + QOpenGLShaderProgram *p = shader->program(); + p->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexCode ? vertexCode : shader->vertexShader()); + p->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader()); + p->link(); + if (!p->isLinked()) + qWarning() << "shader compilation failed:" << endl << p->log(); + } else { + shader->compile(); + } +} + +void QSGDefaultRenderContext::initializeShader(QSGMaterialShader *shader) +{ + shader->program()->bind(); + shader->initialize(); +} + +void QSGDefaultRenderContext::setAttachToGLContext(bool attach) +{ + Q_ASSERT(!isValid()); + m_attachToGLContext = attach; +} + +QSGDefaultRenderContext *QSGDefaultRenderContext::from(QOpenGLContext *context) +{ + return qobject_cast<QSGDefaultRenderContext *>(context->property(QSG_RENDERCONTEXT_PROPERTY).value<QObject *>()); +} + +QT_END_NAMESPACE + + +QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(const QRawFont &font) +{ + if (!m_distanceFieldCacheManager) + m_distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager; + + QSGDistanceFieldGlyphCache *cache = m_distanceFieldCacheManager->cache(font); + if (!cache) { + cache = new QSGDefaultDistanceFieldGlyphCache(m_distanceFieldCacheManager, openglContext(), font); + m_distanceFieldCacheManager->insertCache(font, cache); + } + + return cache; +} diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h new file mode 100644 index 0000000000..bfb15b1eb9 --- /dev/null +++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGDEFAULTRENDERCONTEXT_H +#define QSGDEFAULTRENDERCONTEXT_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qsgcontext_p.h> +#include <QtQuick/private/qsgdepthstencilbuffer_p.h> + +QT_BEGIN_NAMESPACE + +class QOpenGLContext; +class QSGMaterialShader; +class QOpenGLFramebufferObject; + +namespace QSGAtlasTexture { + class Manager; +} + +class QSGDefaultRenderContext : public QSGRenderContext +{ + Q_OBJECT +public: + QSGDefaultRenderContext(QSGContext *context); + + QOpenGLContext *openglContext() const { return m_gl; } + bool isValid() const override { return m_gl; } + + void initialize(void *context) override; + void invalidate() override; + void renderNextFrame(QSGRenderer *renderer, uint fboId) override; + + QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font) override; + + virtual QSharedPointer<QSGDepthStencilBuffer> depthStencilBufferForFbo(QOpenGLFramebufferObject *fbo); + QSGDepthStencilBufferManager *depthStencilBufferManager(); + + QSGTexture *createTexture(const QImage &image, uint flags) const override; + QSGRenderer *createRenderer() override; + + virtual void compileShader(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = 0, const char *fragmentCode = 0); + virtual void initializeShader(QSGMaterialShader *shader); + + void setAttachToGLContext(bool attach); + + static QSGDefaultRenderContext *from(QOpenGLContext *context); + + bool hasBrokenIndexBufferObjects() const { return m_brokenIBOs; } + int maxTextureSize() const { return m_maxTextureSize; } + +protected: + QOpenGLContext *m_gl; + QSGDepthStencilBufferManager *m_depthStencilManager; + int m_maxTextureSize; + bool m_brokenIBOs; + bool m_serializedRender; + bool m_attachToGLContext; + QSGAtlasTexture::Manager *m_atlasManager; + + +}; + +QT_END_NAMESPACE + +#endif // QSGDEFAULTRENDERCONTEXT_H diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 1b0b1acc0e..3d019eab72 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -47,7 +47,6 @@ #include <QtCore/QLibraryInfo> #include <QtCore/private/qabstractanimation_p.h> -#include <QtGui/QOpenGLContext> #include <QtGui/QOffscreenSurface> #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> @@ -59,7 +58,11 @@ #include <QtQuick/private/qsgcontext_p.h> #include <private/qquickprofiler_p.h> -#include <private/qquickshadereffectnode_p.h> +#ifndef QT_NO_OPENGL +# include <QtGui/QOpenGLContext> +# include <private/qsgdefaultrendercontext_p.h> +# include <private/qquickshadereffectnode_p.h> +#endif #ifdef Q_OS_WIN # include <QtCore/qt_windows.h> @@ -69,7 +72,7 @@ QT_BEGIN_NAMESPACE extern bool qsg_useConsistentTiming(); extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); - +#ifndef QT_NO_OPENGL /*! expectations for this manager to work: - one opengl context to render multiple windows @@ -81,7 +84,7 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_ DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP); DEFINE_BOOL_CONFIG_OPTION(qmlForceThreadedRenderer, QML_FORCE_THREADED_RENDERER); // Might trigger graphics driver threading bugs, use at own risk - +#endif QSGRenderLoop *QSGRenderLoop::s_instance = 0; QSGRenderLoop::~QSGRenderLoop() @@ -113,17 +116,20 @@ void QSGRenderLoop::cleanup() */ void QSGRenderLoop::postJob(QQuickWindow *window, QRunnable *job) { - Q_ASSERT(window); Q_ASSERT(job); - +#ifndef QT_NO_OPENGL + Q_ASSERT(window); if (window->openglContext()) { window->openglContext()->makeCurrent(window); job->run(); } - +#else + Q_UNUSED(window) + job->run(); +#endif delete job; } - +#ifndef QT_NO_OPENGL class QSGGuiThreadRenderLoop : public QSGRenderLoop { Q_OBJECT @@ -164,7 +170,7 @@ public: QImage grabContent; }; - +#endif QSGRenderLoop *QSGRenderLoop::instance() { if (!s_instance) { @@ -174,7 +180,7 @@ QSGRenderLoop *QSGRenderLoop::instance() const_cast<QLoggingCategory &>(QSG_LOG_INFO()).setEnabled(QtDebugMsg, true); s_instance = QSGContext::createWindowManager(); - +#ifndef QT_NO_OPENGL if (!s_instance) { enum RenderLoopType { @@ -226,9 +232,10 @@ QSGRenderLoop *QSGRenderLoop::instance() break; } } - +#endif qAddPostRoutine(QSGRenderLoop::cleanup); } + return s_instance; } @@ -263,7 +270,7 @@ void QSGRenderLoop::handleContextCreationFailure(QQuickWindow *window, if (!signalEmitted) qFatal("%s", qPrintable(untranslatedMessage)); } - +#ifndef QT_NO_OPENGL QSGGuiThreadRenderLoop::QSGGuiThreadRenderLoop() : gl(0) { @@ -358,8 +365,10 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) cd->fireOpenGLContextCreated(gl); current = gl->makeCurrent(window); } - if (current) - cd->context->initialize(gl); + if (current) { + auto openglRenderContext = static_cast<QSGDefaultRenderContext *>(cd->context); + openglRenderContext->initialize(gl); + } } else { current = gl->makeCurrent(window); } @@ -480,6 +489,8 @@ void QSGGuiThreadRenderLoop::handleUpdateRequest(QQuickWindow *window) renderWindow(window); } +#endif + #include "qsgrenderloop.moc" QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 7c3405b715..608afcff10 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -64,6 +64,7 @@ #include <private/qqmldebugconnector_p.h> #include <private/qquickshadereffectnode_p.h> +#include <private/qsgdefaultrendercontext_p.h> /* Overall design: @@ -268,7 +269,6 @@ public: QSGRenderThread(QSGThreadedRenderLoop *w, QSGRenderContext *renderContext) : wm(w) , gl(0) - , sgrc(renderContext) , animatorDriver(0) , pendingUpdate(0) , sleeping(false) @@ -277,6 +277,7 @@ public: , window(0) , stopEventProcessing(false) { + sgrc = static_cast<QSGDefaultRenderContext *>(renderContext); #if defined(Q_OS_QNX) && !defined(Q_OS_BLACKBERRY) && defined(Q_PROCESSOR_X86) // The SDP 6.6.0 x86 MESA driver requires a larger stack than the default. setStackSize(1024 * 1024); @@ -325,7 +326,7 @@ public: QSGThreadedRenderLoop *wm; QOpenGLContext *gl; - QSGRenderContext *sgrc; + QSGDefaultRenderContext *sgrc; QAnimationDriver *animatorDriver; diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 901fbbec43..84423a8cfc 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -48,6 +48,7 @@ #include <QtQuick/private/qsgcontext_p.h> #include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qsgdefaultrendercontext_p.h> #include <QtQuick/QQuickWindow> @@ -78,7 +79,7 @@ QSGWindowsRenderLoop::QSGWindowsRenderLoop() , m_updateTimer(0) , m_animationTimer(0) { - m_rc = m_sg->createRenderContext(); + m_rc = static_cast<QSGDefaultRenderContext *>(m_sg->createRenderContext()); m_animationDriver = m_sg->createAnimationDriver(m_sg); m_animationDriver->install(); @@ -341,6 +342,11 @@ void QSGWindowsRenderLoop::maybeUpdate(QQuickWindow *window) maybePostUpdateTimer(); } +QSGRenderContext *QSGWindowsRenderLoop::createRenderContext(QSGContext *) const +{ + return m_rc; +} + bool QSGWindowsRenderLoop::event(QEvent *event) { switch (event->type()) { diff --git a/src/quick/scenegraph/qsgwindowsrenderloop_p.h b/src/quick/scenegraph/qsgwindowsrenderloop_p.h index ad7986035f..9e5d7f04d3 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop_p.h +++ b/src/quick/scenegraph/qsgwindowsrenderloop_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE class QSGRenderContext; +class QSGDefaultRenderContext; class QSGWindowsRenderLoop : public QSGRenderLoop { @@ -83,7 +84,7 @@ public: QAnimationDriver *animationDriver() const { return m_animationDriver; } QSGContext *sceneGraphContext() const { return m_sg; } - QSGRenderContext *createRenderContext(QSGContext *) const { return m_rc; } + QSGRenderContext *createRenderContext(QSGContext *) const; void releaseResources(QQuickWindow *) { } @@ -113,7 +114,7 @@ private: QOpenGLContext *m_gl; QSGContext *m_sg; - QSGRenderContext *m_rc; + QSGDefaultRenderContext *m_rc; QAnimationDriver *m_animationDriver; diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index b4d8b5d231..79971a2b0d 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -5,9 +5,9 @@ # Core API HEADERS += \ - $$PWD/coreapi/qsgbatchrenderer_p.h \ $$PWD/coreapi/qsggeometry.h \ $$PWD/coreapi/qsgmaterial.h \ + $$PWD/coreapi/qsgmaterialshader_p.h \ $$PWD/coreapi/qsgnode.h \ $$PWD/coreapi/qsgnode_p.h \ $$PWD/coreapi/qsgnodeupdater_p.h \ @@ -15,96 +15,115 @@ HEADERS += \ $$PWD/coreapi/qsgabstractrenderer_p.h \ $$PWD/coreapi/qsgrenderer_p.h \ $$PWD/coreapi/qsgrendernode_p.h \ - $$PWD/coreapi/qsggeometry_p.h \ - $$PWD/coreapi/qsgmaterialshader_p.h + $$PWD/coreapi/qsggeometry_p.h SOURCES += \ $$PWD/coreapi/qsgabstractrenderer.cpp \ - $$PWD/coreapi/qsgbatchrenderer.cpp \ $$PWD/coreapi/qsggeometry.cpp \ $$PWD/coreapi/qsgmaterial.cpp \ $$PWD/coreapi/qsgnode.cpp \ $$PWD/coreapi/qsgnodeupdater.cpp \ $$PWD/coreapi/qsgrenderer.cpp \ - $$PWD/coreapi/qsgrendernode.cpp \ - $$PWD/coreapi/qsgshaderrewriter.cpp + $$PWD/coreapi/qsgrendernode.cpp + +contains(QT_CONFIG, opengl(es1|es2)?) { + HEADERS += \ + $$PWD/coreapi/qsgbatchrenderer_p.h + SOURCES += \ + $$PWD/coreapi/qsgbatchrenderer.cpp \ + $$PWD/coreapi/qsgshaderrewriter.cpp +} # Util API HEADERS += \ $$PWD/util/qsgareaallocator_p.h \ - $$PWD/util/qsgatlastexture_p.h \ - $$PWD/util/qsgdepthstencilbuffer_p.h \ $$PWD/util/qsgengine.h \ $$PWD/util/qsgengine_p.h \ - $$PWD/util/qsgflatcolormaterial.h \ - $$PWD/util/qsgsimplematerial.h \ $$PWD/util/qsgsimplerectnode.h \ $$PWD/util/qsgsimpletexturenode.h \ - $$PWD/util/qsgtexturematerial.h \ - $$PWD/util/qsgtexturematerial_p.h \ - $$PWD/util/qsgvertexcolormaterial.h \ $$PWD/util/qsgtexture.h \ $$PWD/util/qsgtexture_p.h \ $$PWD/util/qsgtextureprovider.h \ - $$PWD/util/qsgdefaultpainternode_p.h \ $$PWD/util/qsgdistancefieldutil_p.h \ - $$PWD/util/qsgshadersourcebuilder_p.h + $$PWD/util/qsgflatcolormaterial.h \ + $$PWD/util/qsgsimplematerial.h \ + $$PWD/util/qsgtexturematerial.h \ + $$PWD/util/qsgtexturematerial_p.h \ + $$PWD/util/qsgvertexcolormaterial.h SOURCES += \ $$PWD/util/qsgareaallocator.cpp \ - $$PWD/util/qsgatlastexture.cpp \ - $$PWD/util/qsgdepthstencilbuffer.cpp \ $$PWD/util/qsgengine.cpp \ - $$PWD/util/qsgflatcolormaterial.cpp \ $$PWD/util/qsgsimplerectnode.cpp \ $$PWD/util/qsgsimpletexturenode.cpp \ - $$PWD/util/qsgtexturematerial.cpp \ - $$PWD/util/qsgvertexcolormaterial.cpp \ $$PWD/util/qsgtexture.cpp \ $$PWD/util/qsgtextureprovider.cpp \ - $$PWD/util/qsgdefaultpainternode.cpp \ $$PWD/util/qsgdistancefieldutil.cpp \ + $$PWD/util/qsgflatcolormaterial.cpp \ $$PWD/util/qsgsimplematerial.cpp \ - $$PWD/util/qsgshadersourcebuilder.cpp + $$PWD/util/qsgtexturematerial.cpp \ + $$PWD/util/qsgvertexcolormaterial.cpp +contains(QT_CONFIG, opengl(es1|es2)?) { + HEADERS += \ + $$PWD/util/qsgdepthstencilbuffer_p.h \ + $$PWD/util/qsgshadersourcebuilder_p.h \ + $$PWD/util/qsgatlastexture_p.h + SOURCES += \ + $$PWD/util/qsgdepthstencilbuffer.cpp \ + $$PWD/util/qsgatlastexture.cpp \ + $$PWD/util/qsgshadersourcebuilder.cpp +} + # QML / Adaptations API HEADERS += \ $$PWD/qsgadaptationlayer_p.h \ $$PWD/qsgcontext_p.h \ $$PWD/qsgcontextplugin_p.h \ - $$PWD/qsgdefaultglyphnode_p.h \ - $$PWD/qsgdefaultdistancefieldglyphcache_p.h \ - $$PWD/qsgdistancefieldglyphnode_p.h \ - $$PWD/qsgdistancefieldglyphnode_p_p.h \ - $$PWD/qsgdefaultglyphnode_p_p.h \ - $$PWD/qsgdefaultimagenode_p.h \ - $$PWD/qsgdefaultrectanglenode_p.h \ $$PWD/qsgbasicrectanglenode_p.h \ $$PWD/qsgbasicimagenode_p.h \ $$PWD/qsgbasicglyphnode_p.h \ - $$PWD/qsgrenderloop_p.h \ - $$PWD/qsgthreadedrenderloop_p.h \ - $$PWD/qsgwindowsrenderloop_p.h \ - $$PWD/qsgdefaultlayer_p.h + $$PWD/qsgrenderloop_p.h SOURCES += \ $$PWD/qsgadaptationlayer.cpp \ $$PWD/qsgcontext.cpp \ $$PWD/qsgcontextplugin.cpp \ - $$PWD/qsgdefaultglyphnode.cpp \ - $$PWD/qsgdefaultglyphnode_p.cpp \ - $$PWD/qsgdefaultdistancefieldglyphcache.cpp \ - $$PWD/qsgdistancefieldglyphnode.cpp \ - $$PWD/qsgdistancefieldglyphnode_p.cpp \ - $$PWD/qsgdefaultimagenode.cpp \ - $$PWD/qsgdefaultrectanglenode.cpp \ $$PWD/qsgbasicrectanglenode.cpp \ $$PWD/qsgbasicimagenode.cpp \ $$PWD/qsgbasicglyphnode.cpp \ - $$PWD/qsgrenderloop.cpp \ - $$PWD/qsgthreadedrenderloop.cpp \ - $$PWD/qsgwindowsrenderloop.cpp \ - $$PWD/qsgdefaultlayer.cpp + $$PWD/qsgrenderloop.cpp + +contains(QT_CONFIG, opengl(es1|es2)?) { + SOURCES += \ + $$PWD/qsgdefaultglyphnode.cpp \ + $$PWD/qsgdefaultglyphnode_p.cpp \ + $$PWD/qsgdefaultdistancefieldglyphcache.cpp \ + $$PWD/qsgdistancefieldglyphnode.cpp \ + $$PWD/qsgdistancefieldglyphnode_p.cpp \ + $$PWD/qsgdefaultimagenode.cpp \ + $$PWD/qsgdefaultrectanglenode.cpp \ + $$PWD/qsgdefaultrendercontext.cpp \ + $$PWD/qsgdefaultcontext.cpp \ + $$PWD/util/qsgdefaultpainternode.cpp \ + $$PWD/qsgdefaultlayer.cpp \ + $$PWD/qsgthreadedrenderloop.cpp \ + $$PWD/qsgwindowsrenderloop.cpp + HEADERS += \ + $$PWD/qsgdefaultglyphnode_p.h \ + $$PWD/qsgdefaultdistancefieldglyphcache_p.h \ + $$PWD/qsgdistancefieldglyphnode_p.h \ + $$PWD/qsgdistancefieldglyphnode_p_p.h \ + $$PWD/qsgdefaultglyphnode_p_p.h \ + $$PWD/qsgdefaultimagenode_p.h \ + $$PWD/qsgdefaultrectanglenode_p.h \ + $$PWD/qsgdefaultrendercontext_p.h \ + $$PWD/qsgdefaultcontext_p.h \ + $$PWD/util/qsgdefaultpainternode_p.h \ + $$PWD/qsgdefaultlayer_p.h \ + $$PWD/qsgthreadedrenderloop_p.h \ + $$PWD/qsgwindowsrenderloop_p.h +} # Built-in, non-plugin-based adaptations include(adaptations/adaptations.pri) @@ -112,71 +131,73 @@ include(adaptations/adaptations.pri) RESOURCES += \ $$PWD/scenegraph.qrc -OTHER_FILES += \ - $$PWD/shaders/24bittextmask.frag \ - $$PWD/shaders/8bittextmask.frag \ - $$PWD/shaders/distancefieldoutlinetext.frag \ - $$PWD/shaders/distancefieldshiftedtext.frag \ - $$PWD/shaders/distancefieldshiftedtext.vert \ - $$PWD/shaders/distancefieldtext.frag \ - $$PWD/shaders/distancefieldtext.vert \ - $$PWD/shaders/flatcolor.frag \ - $$PWD/shaders/flatcolor.vert \ - $$PWD/shaders/hiqsubpixeldistancefieldtext.frag \ - $$PWD/shaders/hiqsubpixeldistancefieldtext.vert \ - $$PWD/shaders/loqsubpixeldistancefieldtext.frag \ - $$PWD/shaders/loqsubpixeldistancefieldtext.vert \ - $$PWD/shaders/opaquetexture.frag \ - $$PWD/shaders/opaquetexture.vert \ - $$PWD/shaders/outlinedtext.frag \ - $$PWD/shaders/outlinedtext.vert \ - $$PWD/shaders/rendernode.frag \ - $$PWD/shaders/rendernode.vert \ - $$PWD/shaders/smoothcolor.frag \ - $$PWD/shaders/smoothcolor.vert \ - $$PWD/shaders/smoothtexture.frag \ - $$PWD/shaders/smoothtexture.vert \ - $$PWD/shaders/stencilclip.frag \ - $$PWD/shaders/stencilclip.vert \ - $$PWD/shaders/styledtext.frag \ - $$PWD/shaders/styledtext.vert \ - $$PWD/shaders/textmask.frag \ - $$PWD/shaders/textmask.vert \ - $$PWD/shaders/texture.frag \ - $$PWD/shaders/vertexcolor.frag \ - $$PWD/shaders/vertexcolor.vert \ - $$PWD/shaders/24bittextmask_core.frag \ - $$PWD/shaders/8bittextmask_core.frag \ - $$PWD/shaders/distancefieldoutlinetext_core.frag \ - $$PWD/shaders/distancefieldshiftedtext_core.frag \ - $$PWD/shaders/distancefieldshiftedtext_core.vert \ - $$PWD/shaders/distancefieldtext_core.frag \ - $$PWD/shaders/distancefieldtext_core.vert \ - $$PWD/shaders/flatcolor_core.frag \ - $$PWD/shaders/flatcolor_core.vert \ - $$PWD/shaders/hiqsubpixeldistancefieldtext_core.frag \ - $$PWD/shaders/hiqsubpixeldistancefieldtext_core.vert \ - $$PWD/shaders/loqsubpixeldistancefieldtext_core.frag \ - $$PWD/shaders/loqsubpixeldistancefieldtext_core.vert \ - $$PWD/shaders/opaquetexture_core.frag \ - $$PWD/shaders/opaquetexture_core.vert \ - $$PWD/shaders/outlinedtext_core.frag \ - $$PWD/shaders/outlinedtext_core.vert \ - $$PWD/shaders/rendernode_core.frag \ - $$PWD/shaders/rendernode_core.vert \ - $$PWD/shaders/smoothcolor_core.frag \ - $$PWD/shaders/smoothcolor_core.vert \ - $$PWD/shaders/smoothtexture_core.frag \ - $$PWD/shaders/smoothtexture_core.vert \ - $$PWD/shaders/stencilclip_core.frag \ - $$PWD/shaders/stencilclip_core.vert \ - $$PWD/shaders/styledtext_core.frag \ - $$PWD/shaders/styledtext_core.vert \ - $$PWD/shaders/textmask_core.frag \ - $$PWD/shaders/textmask_core.vert \ - $$PWD/shaders/texture_core.frag \ - $$PWD/shaders/vertexcolor_core.frag \ - $$PWD/shaders/vertexcolor_core.vert \ - scenegraph/shaders/visualization.frag \ - scenegraph/shaders/visualization.vert - +# OpenGL Shaders +contains(QT_CONFIG, opengl(es1|es2)?) { + OTHER_FILES += \ + $$PWD/shaders/24bittextmask.frag \ + $$PWD/shaders/8bittextmask.frag \ + $$PWD/shaders/distancefieldoutlinetext.frag \ + $$PWD/shaders/distancefieldshiftedtext.frag \ + $$PWD/shaders/distancefieldshiftedtext.vert \ + $$PWD/shaders/distancefieldtext.frag \ + $$PWD/shaders/distancefieldtext.vert \ + $$PWD/shaders/flatcolor.frag \ + $$PWD/shaders/flatcolor.vert \ + $$PWD/shaders/hiqsubpixeldistancefieldtext.frag \ + $$PWD/shaders/hiqsubpixeldistancefieldtext.vert \ + $$PWD/shaders/loqsubpixeldistancefieldtext.frag \ + $$PWD/shaders/loqsubpixeldistancefieldtext.vert \ + $$PWD/shaders/opaquetexture.frag \ + $$PWD/shaders/opaquetexture.vert \ + $$PWD/shaders/outlinedtext.frag \ + $$PWD/shaders/outlinedtext.vert \ + $$PWD/shaders/rendernode.frag \ + $$PWD/shaders/rendernode.vert \ + $$PWD/shaders/smoothcolor.frag \ + $$PWD/shaders/smoothcolor.vert \ + $$PWD/shaders/smoothtexture.frag \ + $$PWD/shaders/smoothtexture.vert \ + $$PWD/shaders/stencilclip.frag \ + $$PWD/shaders/stencilclip.vert \ + $$PWD/shaders/styledtext.frag \ + $$PWD/shaders/styledtext.vert \ + $$PWD/shaders/textmask.frag \ + $$PWD/shaders/textmask.vert \ + $$PWD/shaders/texture.frag \ + $$PWD/shaders/vertexcolor.frag \ + $$PWD/shaders/vertexcolor.vert \ + $$PWD/shaders/24bittextmask_core.frag \ + $$PWD/shaders/8bittextmask_core.frag \ + $$PWD/shaders/distancefieldoutlinetext_core.frag \ + $$PWD/shaders/distancefieldshiftedtext_core.frag \ + $$PWD/shaders/distancefieldshiftedtext_core.vert \ + $$PWD/shaders/distancefieldtext_core.frag \ + $$PWD/shaders/distancefieldtext_core.vert \ + $$PWD/shaders/flatcolor_core.frag \ + $$PWD/shaders/flatcolor_core.vert \ + $$PWD/shaders/hiqsubpixeldistancefieldtext_core.frag \ + $$PWD/shaders/hiqsubpixeldistancefieldtext_core.vert \ + $$PWD/shaders/loqsubpixeldistancefieldtext_core.frag \ + $$PWD/shaders/loqsubpixeldistancefieldtext_core.vert \ + $$PWD/shaders/opaquetexture_core.frag \ + $$PWD/shaders/opaquetexture_core.vert \ + $$PWD/shaders/outlinedtext_core.frag \ + $$PWD/shaders/outlinedtext_core.vert \ + $$PWD/shaders/rendernode_core.frag \ + $$PWD/shaders/rendernode_core.vert \ + $$PWD/shaders/smoothcolor_core.frag \ + $$PWD/shaders/smoothcolor_core.vert \ + $$PWD/shaders/smoothtexture_core.frag \ + $$PWD/shaders/smoothtexture_core.vert \ + $$PWD/shaders/stencilclip_core.frag \ + $$PWD/shaders/stencilclip_core.vert \ + $$PWD/shaders/styledtext_core.frag \ + $$PWD/shaders/styledtext_core.vert \ + $$PWD/shaders/textmask_core.frag \ + $$PWD/shaders/textmask_core.vert \ + $$PWD/shaders/texture_core.frag \ + $$PWD/shaders/vertexcolor_core.frag \ + $$PWD/shaders/vertexcolor_core.vert \ + $$PWD/shaders/visualization.frag \ + $$PWD/shaders/visualization.vert +} diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index 57468e5799..edf3739d6c 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -44,6 +44,7 @@ #include <QtCore/QtMath> #include <QtGui/QOpenGLContext> +#include <QtGui/QOpenGLFunctions> #include <QtGui/QGuiApplication> #include <QtGui/QScreen> #include <QtGui/QSurface> diff --git a/src/quick/scenegraph/util/qsgatlastexture_p.h b/src/quick/scenegraph/util/qsgatlastexture_p.h index c6f1e72a4d..da5acb3fea 100644 --- a/src/quick/scenegraph/util/qsgatlastexture_p.h +++ b/src/quick/scenegraph/util/qsgatlastexture_p.h @@ -104,17 +104,17 @@ public: QSize size() const { return m_size; } - GLuint internalFormat() const { return m_internalFormat; } - GLuint externalFormat() const { return m_externalFormat; } + uint internalFormat() const { return m_internalFormat; } + uint externalFormat() const { return m_externalFormat; } private: QSGAreaAllocator m_allocator; - GLuint m_texture_id; + unsigned int m_texture_id; QSize m_size; QList<Texture *> m_pending_uploads; - GLuint m_internalFormat; - GLuint m_externalFormat; + uint m_internalFormat; + uint m_externalFormat; uint m_allocated : 1; uint m_use_bgra_fallback: 1; diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp index 2deb993a6e..4dd60c76f5 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp +++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp @@ -41,6 +41,7 @@ #include <QtQuick/private/qquickpainteditem_p.h> +#include <QtQuick/private/qsgdefaultrendercontext_p.h> #include <QtQuick/private/qsgcontext_p.h> #include <private/qopenglextensions_p.h> #include <qopenglframebufferobject.h> @@ -96,7 +97,7 @@ QSGDefaultPainterNode::QSGDefaultPainterNode(QQuickPaintedItem *item) , m_dirtyRenderTarget(false) , m_dirtyTexture(false) { - m_context = static_cast<QQuickPaintedItemPrivate *>(QObjectPrivate::get(item))->sceneGraphRenderContext(); + m_context = static_cast<QSGDefaultRenderContext *>(static_cast<QQuickPaintedItemPrivate *>(QObjectPrivate::get(item))->sceneGraphRenderContext()); setMaterial(&m_materialO); setOpaqueMaterial(&m_material); diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h index 3cabe01511..069ef155b1 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h +++ b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE class QOpenGLFramebufferObject; class QOpenGLPaintDevice; +class QSGDefaultRenderContext; class Q_QUICK_PRIVATE_EXPORT QSGPainterTexture : public QSGPlainTexture { @@ -127,7 +128,7 @@ private: void updateRenderTarget(); void updateFBOSize(); - QSGRenderContext *m_context; + QSGDefaultRenderContext *m_context; QQuickPaintedItem::RenderTarget m_preferredRenderTarget; QQuickPaintedItem::RenderTarget m_actualRenderTarget; diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp index 5eb6a6f593..65a6bcd52c 100644 --- a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp +++ b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp @@ -40,7 +40,9 @@ #include "qsgdistancefieldutil_p.h" #include <private/qsgadaptationlayer_p.h> -#include <QtGui/private/qopenglengineshadersource_p.h> +#ifndef QT_NO_OPENGL +# include <QtGui/private/qopenglengineshadersource_p.h> +#endif #include <QtQuick/private/qsgcontext_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp index 1ef98d222d..da7a65cfec 100644 --- a/src/quick/scenegraph/util/qsgengine.cpp +++ b/src/quick/scenegraph/util/qsgengine.cpp @@ -44,6 +44,11 @@ #include <private/qsgrenderer_p.h> #include <private/qsgtexture_p.h> +#ifndef QT_NO_OPENGL +# include <QtGui/QOpenGLContext> +# include <private/qsgdefaultrendercontext_p.h> +#endif + QT_BEGIN_NAMESPACE @@ -83,7 +88,7 @@ QT_BEGIN_NAMESPACE QSGEnginePrivate::QSGEnginePrivate() : sgContext(QSGContext::createDefaultContext()) - , sgRenderContext(new QSGRenderContext(sgContext.data())) + , sgRenderContext(sgContext.data()->createRenderContext()) { } @@ -110,17 +115,23 @@ QSGEngine::~QSGEngine() */ void QSGEngine::initialize(QOpenGLContext *context) { +#ifndef QT_NO_OPENGL Q_D(QSGEngine); if (QOpenGLContext::currentContext() != context) { qWarning("WARNING: The context must be current before calling QSGEngine::initialize."); return; } - if (!d->sgRenderContext->isValid()) { - d->sgRenderContext->setAttachToGLContext(false); - d->sgRenderContext->initialize(context); + auto openGLRenderContext = static_cast<QSGDefaultRenderContext *>(d->sgRenderContext.data()); + + if (openGLRenderContext != nullptr && !openGLRenderContext->isValid()) { + openGLRenderContext->setAttachToGLContext(false); + openGLRenderContext->initialize(context); connect(context, &QOpenGLContext::aboutToBeDestroyed, this, &QSGEngine::invalidate); } +#else + Q_UNUSED(context) +#endif } /*! diff --git a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp index 005c7a043d..a3dfc555c4 100644 --- a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp +++ b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp @@ -39,8 +39,9 @@ #include "qsgflatcolormaterial.h" #include <private/qsgmaterialshader_p.h> - -#include <qopenglshaderprogram.h> +#ifndef QT_NO_OPENGL +# include <qopenglshaderprogram.h> +#endif QT_BEGIN_NAMESPACE @@ -66,14 +67,16 @@ QSGMaterialType FlatColorMaterialShader::type; FlatColorMaterialShader::FlatColorMaterialShader() : QSGMaterialShader(*new QSGMaterialShaderPrivate) { +#ifndef QT_NO_OPENGL setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/flatcolor.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/flatcolor.frag")); +#endif } void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { +#ifndef QT_NO_OPENGL Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); - QSGFlatColorMaterial *oldMaterial = static_cast<QSGFlatColorMaterial *>(oldEffect); QSGFlatColorMaterial *newMaterial = static_cast<QSGFlatColorMaterial *>(newEffect); @@ -90,6 +93,11 @@ void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial if (state.isMatrixDirty()) program()->setUniformValue(m_matrix_id, state.combinedMatrix()); +#else + Q_UNUSED(state) + Q_UNUSED(newEffect) + Q_UNUSED(oldEffect) +#endif } char const *const *FlatColorMaterialShader::attributeNames() const @@ -100,8 +108,10 @@ char const *const *FlatColorMaterialShader::attributeNames() const void FlatColorMaterialShader::initialize() { +#ifndef QT_NO_OPENGL m_matrix_id = program()->uniformLocation("matrix"); m_color_id = program()->uniformLocation("color"); +#endif } diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index 74390334c4..751406f12c 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "qsgtexture_p.h" -#include <qopenglfunctions.h> #include <QtQuick/private/qsgcontext_p.h> #include <qthread.h> #include <qmath.h> @@ -46,9 +45,12 @@ #include <private/qqmlglobal_p.h> #include <QtGui/qguiapplication.h> #include <QtGui/qpa/qplatformnativeinterface.h> -#include <QtGui/qopenglcontext.h> -#include <QtGui/qopenglfunctions.h> - +#ifndef QT_NO_OPENGL +# include <qopenglfunctions.h> +# include <QtGui/qopenglcontext.h> +# include <QtGui/qopenglfunctions.h> +# include <private/qsgdefaultrendercontext_p.h> +#endif #include <private/qsgmaterialshader_p.h> #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && !defined(__UCLIBC__) @@ -278,6 +280,7 @@ Q_GLOBAL_STATIC(QMutex, qsg_valid_texture_mutex) bool qsg_safeguard_texture(QSGTexture *texture) { +#ifndef QT_NO_OPENGL QMutexLocker locker(qsg_valid_texture_mutex()); if (!qsg_valid_texture_set()->contains(texture)) { qWarning() << "Invalid texture accessed:" << (void *) texture; @@ -285,6 +288,7 @@ bool qsg_safeguard_texture(QSGTexture *texture) QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, 0); return false; } +#endif return true; } #endif @@ -517,6 +521,7 @@ QSGTexture::WrapMode QSGTexture::verticalWrapMode() const */ void QSGTexture::updateBindOptions(bool force) { +#ifndef QT_NO_OPENGL Q_D(QSGTexture); QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); force |= isAtlasTexture(); @@ -551,6 +556,9 @@ void QSGTexture::updateBindOptions(bool force) funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, d->verticalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); d->wrapChanged = false; } +#else + Q_UNUSED(force) +#endif } QSGPlainTexture::QSGPlainTexture() @@ -568,8 +576,10 @@ QSGPlainTexture::QSGPlainTexture() QSGPlainTexture::~QSGPlainTexture() { +#ifndef QT_NO_OPENGL if (m_texture_id && m_owns_texture && QOpenGLContext::currentContext()) QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id); +#endif } void qsg_swizzleBGRAToRGBA(QImage *image) @@ -601,8 +611,10 @@ int QSGPlainTexture::textureId() const // or ~QSGPlainTexture so just keep it minimal here. return 0; } else if (m_texture_id == 0){ +#ifndef QT_NO_OPENGL // Generate a texture id for use later and return it. QOpenGLContext::currentContext()->functions()->glGenTextures(1, &const_cast<QSGPlainTexture *>(this)->m_texture_id); +#endif return m_texture_id; } } @@ -611,8 +623,10 @@ int QSGPlainTexture::textureId() const void QSGPlainTexture::setTextureId(int id) { +#ifndef QT_NO_OPENGL if (m_texture_id && m_owns_texture) QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id); +#endif m_texture_id = id; m_dirty_texture = false; @@ -623,6 +637,7 @@ void QSGPlainTexture::setTextureId(int id) void QSGPlainTexture::bind() { +#ifndef QT_NO_OPENGL QOpenGLContext *context = QOpenGLContext::currentContext(); QOpenGLFunctions *funcs = context->functions(); if (!m_dirty_texture) { @@ -684,7 +699,7 @@ void QSGPlainTexture::bind() // based on QSGTexture::textureSize which is updated after this, so that // should be ok. int max; - if (QSGRenderContext *rc = QSGRenderContext::from(context)) + if (auto rc = QSGDefaultRenderContext::from(context)) max = rc->maxTextureSize(); else funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); @@ -789,6 +804,7 @@ void QSGPlainTexture::bind() m_dirty_bind_options = false; if (!m_retain_image) m_image = QImage(); +#endif } diff --git a/src/quick/scenegraph/util/qsgtexture_p.h b/src/quick/scenegraph/util/qsgtexture_p.h index 5c358aecc3..a0d7eb41e3 100644 --- a/src/quick/scenegraph/util/qsgtexture_p.h +++ b/src/quick/scenegraph/util/qsgtexture_p.h @@ -53,9 +53,9 @@ #include <QtQuick/qtquickglobal.h> #include <private/qobject_p.h> - -#include <QtGui/qopengl.h> - +#ifndef QT_NO_OPENGL +# include <QtGui/qopengl.h> +#endif #include "qsgtexture.h" #include <QtQuick/private/qsgcontext_p.h> @@ -110,7 +110,7 @@ public: protected: QImage m_image; - GLuint m_texture_id; + uint m_texture_id; QSize m_texture_size; QRectF m_texture_rect; diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp index 4eb38842dc..35c5ace889 100644 --- a/src/quick/scenegraph/util/qsgtexturematerial.cpp +++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp @@ -39,9 +39,10 @@ #include "qsgtexturematerial_p.h" #include "qsgtexture_p.h" - -#include <QtGui/qopenglshaderprogram.h> -#include <QtGui/qopenglfunctions.h> +#ifndef QT_NO_OPENGL +# include <QtGui/qopenglshaderprogram.h> +# include <QtGui/qopenglfunctions.h> +#endif QT_BEGIN_NAMESPACE @@ -56,8 +57,10 @@ QSGMaterialType QSGOpaqueTextureMaterialShader::type; QSGOpaqueTextureMaterialShader::QSGOpaqueTextureMaterialShader() : QSGMaterialShader() { +#ifndef QT_NO_OPENGL setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/opaquetexture.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/opaquetexture.frag")); +#endif } char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const @@ -68,7 +71,9 @@ char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const void QSGOpaqueTextureMaterialShader::initialize() { +#ifndef QT_NO_OPENGL m_matrix_id = program()->uniformLocation("qt_Matrix"); +#endif } void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) @@ -88,6 +93,7 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa t->setHorizontalWrapMode(tx->horizontalWrapMode()); t->setVerticalWrapMode(tx->verticalWrapMode()); +#ifndef QT_NO_OPENGL bool npotSupported = const_cast<QOpenGLContext *>(state.context()) ->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat); if (!npotSupported) { @@ -98,16 +104,17 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa t->setVerticalWrapMode(QSGTexture::ClampToEdge); } } - +#endif t->setMipmapFiltering(tx->mipmapFiltering()); if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId()) t->bind(); else t->updateBindOptions(); - +#ifndef QT_NO_OPENGL if (state.isMatrixDirty()) program()->setUniformValue(m_matrix_id, state.combinedMatrix()); +#endif } @@ -362,22 +369,27 @@ QSGMaterialShader *QSGTextureMaterial::createShader() const QSGTextureMaterialShader::QSGTextureMaterialShader() : QSGOpaqueTextureMaterialShader() { +#ifndef QT_NO_OPENGL setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/texture.frag")); +#endif } void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); +#ifndef QT_NO_OPENGL if (state.isOpacityDirty()) program()->setUniformValue(m_opacity_id, state.opacity()); - +#endif QSGOpaqueTextureMaterialShader::updateState(state, newEffect, oldEffect); } void QSGTextureMaterialShader::initialize() { QSGOpaqueTextureMaterialShader::initialize(); +#ifndef QT_NO_OPENGL m_opacity_id = program()->uniformLocation("opacity"); +#endif } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp index 91d7ece90d..3897dfe4b2 100644 --- a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp +++ b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp @@ -38,9 +38,9 @@ ****************************************************************************/ #include "qsgvertexcolormaterial.h" - -#include <qopenglshaderprogram.h> - +#ifndef QT_NO_OPENGL +# include <qopenglshaderprogram.h> +#endif QT_BEGIN_NAMESPACE class QSGVertexColorMaterialShader : public QSGMaterialShader @@ -65,17 +65,23 @@ QSGMaterialType QSGVertexColorMaterialShader::type; QSGVertexColorMaterialShader::QSGVertexColorMaterialShader() : QSGMaterialShader() { +#ifndef QT_NO_OPENGL setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/vertexcolor.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/vertexcolor.frag")); +#endif } void QSGVertexColorMaterialShader::updateState(const RenderState &state, QSGMaterial * /*newEffect*/, QSGMaterial *) { +#ifndef QT_NO_OPENGL if (state.isOpacityDirty()) program()->setUniformValue(m_opacity_id, state.opacity()); if (state.isMatrixDirty()) program()->setUniformValue(m_matrix_id, state.combinedMatrix()); +#else + Q_UNUSED(state) +#endif } char const *const *QSGVertexColorMaterialShader::attributeNames() const @@ -86,8 +92,10 @@ char const *const *QSGVertexColorMaterialShader::attributeNames() const void QSGVertexColorMaterialShader::initialize() { +#ifndef QT_NO_OPENGL m_matrix_id = program()->uniformLocation("matrix"); m_opacity_id = program()->uniformLocation("opacity"); +#endif } |