aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/quick/quickwidgets/quickwidget/customgl.qml59
-rw-r--r--examples/quick/quickwidgets/quickwidget/fbitem.cpp90
-rw-r--r--examples/quick/quickwidgets/quickwidget/fbitem.h53
-rw-r--r--examples/quick/quickwidgets/quickwidget/main.cpp38
-rw-r--r--examples/quick/quickwidgets/quickwidget/quickwidget.pro3
-rw-r--r--examples/quick/quickwidgets/quickwidget/quickwidget.qrc2
-rw-r--r--examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml66
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp29
-rw-r--r--src/qml/compiler/qv4compileddata.cpp17
-rw-r--r--src/qml/compiler/qv4compileddata_p.h2
-rw-r--r--src/qml/qml/qqmltypeloader.cpp30
-rw-r--r--src/qml/qml/qqmltypeloader_p.h1
-rw-r--r--src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc44
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp6
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp31
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h3
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp4
18 files changed, 429 insertions, 51 deletions
diff --git a/examples/quick/quickwidgets/quickwidget/customgl.qml b/examples/quick/quickwidgets/quickwidget/customgl.qml
new file mode 100644
index 0000000000..81e33e1ac9
--- /dev/null
+++ b/examples/quick/quickwidgets/quickwidget/customgl.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QuickWidgetExample 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ FbItem {
+ anchors.fill: parent
+ anchors.margins: 10
+ }
+
+ Text {
+ anchors.left: parent.left
+ anchors.bottom: parent.bottom
+ anchors.margins: 15
+ text: "QQuickFramebufferObject with animated clear color"
+ color: "white"
+ }
+}
diff --git a/examples/quick/quickwidgets/quickwidget/fbitem.cpp b/examples/quick/quickwidgets/quickwidget/fbitem.cpp
new file mode 100644
index 0000000000..fc2a4ea7ad
--- /dev/null
+++ b/examples/quick/quickwidgets/quickwidget/fbitem.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fbitem.h"
+#include <QtGui/QOpenGLFramebufferObject>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFunctions>
+#include <QtCore/QDebug>
+
+#ifndef QT_NO_OPENGL
+class FbRenderer : public QQuickFramebufferObject::Renderer
+{
+public:
+ FbRenderer() : c(0), dir(1) { }
+
+ // The lifetime of the FBO and this class depends on how QQuickWidget
+ // manages the scenegraph and context when it comes to showing and hiding
+ // the widget. The actual behavior is proven by the debug prints.
+ ~FbRenderer() {
+ qDebug("FbRenderer destroyed");
+ }
+
+ void render() {
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ f->glClearColor(c, 0, 0, 1);
+ f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ c += 0.01f * dir;
+ if (c >= 1.0f || c <= 0.0f)
+ dir *= -1;
+ update();
+ }
+
+ QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) {
+ qDebug() << "Creating FBO" << size;
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ return new QOpenGLFramebufferObject(size, format);
+ }
+
+private:
+ float c;
+ int dir;
+};
+#endif
+
+QQuickFramebufferObject::Renderer *FbItem::createRenderer() const
+{
+#ifndef QT_NO_OPENGL
+ return new FbRenderer;
+#else
+ return nullptr;
+#endif
+}
diff --git a/examples/quick/quickwidgets/quickwidget/fbitem.h b/examples/quick/quickwidgets/quickwidget/fbitem.h
new file mode 100644
index 0000000000..59280eb3b8
--- /dev/null
+++ b/examples/quick/quickwidgets/quickwidget/fbitem.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FBITEM_H
+#define FBITEM_H
+
+#include <QtQuick/QQuickFramebufferObject>
+
+class FbItem : public QQuickFramebufferObject
+{
+ Q_OBJECT
+public:
+ Renderer *createRenderer() const;
+};
+
+#endif
diff --git a/examples/quick/quickwidgets/quickwidget/main.cpp b/examples/quick/quickwidgets/quickwidget/main.cpp
index 65258d958e..2f73447a5d 100644
--- a/examples/quick/quickwidgets/quickwidget/main.cpp
+++ b/examples/quick/quickwidgets/quickwidget/main.cpp
@@ -41,6 +41,7 @@
#include <QQuickWidget>
#include <QQmlError>
#include <QtWidgets>
+#include "fbitem.h"
class MainWindow : public QMainWindow {
Q_OBJECT
@@ -52,6 +53,7 @@ private slots:
void sceneGraphError(QQuickWindow::SceneGraphError error, const QString &message);
void grabToFile();
void renderToFile();
+ void createQuickWidgetsInTabs(QMdiArea *mdiArea);
private:
QQuickWidget *m_quickWidget;
@@ -74,7 +76,7 @@ MainWindow::MainWindow()
QLCDNumber *lcd = new QLCDNumber;
lcd->display(1337);
lcd->setMinimumSize(250,100);
- centralWidget ->addSubWindow(lcd);
+ centralWidget->addSubWindow(lcd);
QUrl source("qrc:quickwidget/rotatingsquare.qml");
@@ -86,14 +88,42 @@ MainWindow::MainWindow()
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView );
m_quickWidget->setSource(source);
- centralWidget ->addSubWindow(m_quickWidget);
+ centralWidget->addSubWindow(m_quickWidget);
setCentralWidget(centralWidget);
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
- fileMenu->addAction(tr("Grab to imFage"), this, &MainWindow::grabToFile);
+ fileMenu->addAction(tr("Grab to image"), this, &MainWindow::grabToFile);
fileMenu->addAction(tr("Render to pixmap"), this, &MainWindow::renderToFile);
fileMenu->addAction(tr("Quit"), qApp, &QCoreApplication::quit);
+
+ QMenu *windowMenu = menuBar()->addMenu(tr("&Window"));
+ windowMenu->addAction(tr("Add tab widget"), this,
+ [this, centralWidget] { createQuickWidgetsInTabs(centralWidget); });
+}
+
+void MainWindow::createQuickWidgetsInTabs(QMdiArea *mdiArea)
+{
+ QTabWidget *tabWidget = new QTabWidget;
+
+ const QSize size(400, 400);
+
+ QQuickWidget *w = new QQuickWidget;
+ w->resize(size);
+ w->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ w->setSource(QUrl("qrc:quickwidget/rotatingsquaretab.qml"));
+
+ tabWidget->addTab(w, tr("Plain Quick content"));
+
+ w = new QQuickWidget;
+ w->resize(size);
+ w->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ w->setSource(QUrl("qrc:quickwidget/customgl.qml"));
+
+ tabWidget->addTab(w, tr("Custom OpenGL drawing"));
+
+ mdiArea->addSubWindow(tabWidget);
+ tabWidget->show();
}
void MainWindow::quickWidgetStatusChanged(QQuickWidget::Status status)
@@ -139,6 +169,8 @@ int main(int argc, char **argv)
{
QApplication app(argc, argv);
+ qmlRegisterType<FbItem>("QuickWidgetExample", 1, 0, "FbItem");
+
MainWindow mainWindow;
mainWindow.show();
diff --git a/examples/quick/quickwidgets/quickwidget/quickwidget.pro b/examples/quick/quickwidgets/quickwidget/quickwidget.pro
index 04fb5541a7..5be006f7fa 100644
--- a/examples/quick/quickwidgets/quickwidget/quickwidget.pro
+++ b/examples/quick/quickwidgets/quickwidget/quickwidget.pro
@@ -3,7 +3,8 @@ QT += core gui quick widgets quickwidgets
TARGET = quickwidget
TEMPLATE = app
-SOURCES += main.cpp
+SOURCES += main.cpp fbitem.cpp
+HEADERS += fbitem.h
RESOURCES += quickwidget.qrc
diff --git a/examples/quick/quickwidgets/quickwidget/quickwidget.qrc b/examples/quick/quickwidgets/quickwidget/quickwidget.qrc
index c073b7b80d..85a49b75ca 100644
--- a/examples/quick/quickwidgets/quickwidget/quickwidget.qrc
+++ b/examples/quick/quickwidgets/quickwidget/quickwidget.qrc
@@ -1,5 +1,7 @@
<RCC>
<qresource prefix="/quickwidget">
<file>rotatingsquare.qml</file>
+ <file>rotatingsquaretab.qml</file>
+ <file>customgl.qml</file>
</qresource>
</RCC>
diff --git a/examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml b/examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml
new file mode 100644
index 0000000000..51c17b9ffb
--- /dev/null
+++ b/examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ gradient: Gradient {
+ GradientStop { position: 0; color: "steelblue" }
+ GradientStop { position: 1; color: "black" }
+ }
+
+ Rectangle {
+ property int d: 100
+ id: square
+ width: d
+ height: d
+ anchors.centerIn: parent
+ color: "green"
+ NumberAnimation on rotation { from: 360; to: 0; duration: 4000; loops: Animation.Infinite; }
+ }
+
+ Text {
+ anchors.centerIn: parent
+ text: "Qt Quick running in a tab widget"
+ color: "purple"
+ font.bold: true
+ font.pointSize: 14
+ }
+}
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index e40666864c..d73ce6f09d 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -47,7 +47,6 @@
#include <private/qv4ssa_p.h>
#include "qqmlpropertycachecreator_p.h"
-#include "qqmlpropertyvalidator_p.h"
#define COMPILE_EXCEPTION(token, desc) \
{ \
@@ -168,34 +167,6 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
compilationUnit->propertyCaches = std::move(m_propertyCaches);
Q_ASSERT(compilationUnit->propertyCaches.count() == static_cast<int>(compilationUnit->data->nObjects));
- // Add to type registry of composites
- if (compilationUnit->propertyCaches.needsVMEMetaObject(qmlUnit->indexOfRootObject))
- engine->registerInternalCompositeType(compilationUnit);
- else {
- const QV4::CompiledData::Object *obj = qmlUnit->objectAt(qmlUnit->indexOfRootObject);
- auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
- Q_ASSERT(typeRef);
- if (typeRef->compilationUnit) {
- compilationUnit->metaTypeId = typeRef->compilationUnit->metaTypeId;
- compilationUnit->listMetaTypeId = typeRef->compilationUnit->listMetaTypeId;
- } else {
- compilationUnit->metaTypeId = typeRef->type->typeId();
- compilationUnit->listMetaTypeId = typeRef->type->qListTypeId();
- }
- }
-
- {
- // Sanity check property bindings
- QQmlPropertyValidator validator(engine, *imports(), compilationUnit);
- QVector<QQmlCompileError> errors = validator.validate();
- if (!errors.isEmpty()) {
- for (const QQmlCompileError &error: qAsConst(errors))
- recordError(error);
- return nullptr;
- }
- }
-
- compilationUnit->updateBindingAndObjectCounters();
if (errors.isEmpty())
return compilationUnit;
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index d2587a547c..b05abdc0c8 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -239,8 +239,23 @@ IdentifierHash<int> CompilationUnit::namedObjectsPerComponent(int componentObjec
return *it;
}
-void CompilationUnit::updateBindingAndObjectCounters()
+void CompilationUnit::finalize(QQmlEnginePrivate *engine)
{
+ // Add to type registry of composites
+ if (propertyCaches.needsVMEMetaObject(data->indexOfRootObject))
+ engine->registerInternalCompositeType(this);
+ else {
+ const QV4::CompiledData::Object *obj = objectAt(data->indexOfRootObject);
+ auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(typeRef);
+ if (typeRef->compilationUnit) {
+ metaTypeId = typeRef->compilationUnit->metaTypeId;
+ listMetaTypeId = typeRef->compilationUnit->listMetaTypeId;
+ } else {
+ metaTypeId = typeRef->type->typeId();
+ listMetaTypeId = typeRef->type->qListTypeId();
+ }
+ }
// Collect some data for instantiation later.
int bindingCount = 0;
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index b960901402..a9a0ebbf51 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -766,7 +766,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount
QHash<int, IdentifierHash<int>> namedObjectsPerComponentCache;
IdentifierHash<int> namedObjectsPerComponent(int componentObjectIndex);
- void updateBindingAndObjectCounters();
+ void finalize(QQmlEnginePrivate *engine);
int totalBindingsCount; // Number of bindings used in this type
int totalParserStatusCount; // Number of instantiated types that are QQmlParserStatus subclasses
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 7ba18cd761..190ac29e33 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -49,6 +49,7 @@
#include <private/qqmlprofiler_p.h>
#include <private/qqmlmemoryprofiler_p.h>
#include <private/qqmltypecompiler_p.h>
+#include <private/qqmlpropertyvalidator_p.h>
#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
@@ -445,6 +446,21 @@ void QQmlDataBlob::setError(const QQmlCompileError &error)
setError(e);
}
+void QQmlDataBlob::setError(const QVector<QQmlCompileError> &errors)
+{
+ QList<QQmlError> finalErrors;
+ finalErrors.reserve(errors.count());
+ for (const QQmlCompileError &error: errors) {
+ QQmlError e;
+ e.setColumn(error.location.column);
+ e.setLine(error.location.line);
+ e.setDescription(error.description);
+ e.setUrl(url());
+ finalErrors << e;
+ }
+ setError(finalErrors);
+}
+
void QQmlDataBlob::setError(const QString &description)
{
QQmlError e;
@@ -2082,6 +2098,20 @@ void QQmlTypeData::done()
compile();
if (!isError()) {
+ QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine());
+ {
+ // Sanity check property bindings
+ QQmlPropertyValidator validator(engine, m_importCache, m_compiledData);
+ QVector<QQmlCompileError> errors = validator.validate();
+ if (!errors.isEmpty()) {
+ setError(errors);
+ }
+ }
+
+ m_compiledData->finalize(engine);
+ }
+
+ if (!isError()) {
QQmlType *type = QQmlMetaType::qmlType(finalUrl(), true);
if (m_compiledData && m_compiledData->data->flags & QV4::CompiledData::Unit::IsSingleton) {
if (!type) {
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 9fd7fb9f51..2030dbf427 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -146,6 +146,7 @@ protected:
void setError(const QQmlError &);
void setError(const QList<QQmlError> &errors);
void setError(const QQmlCompileError &error);
+ void setError(const QVector<QQmlCompileError> &errors);
void setError(const QString &description);
void addDependency(QQmlDataBlob *);
diff --git a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
index d7d2fea281..a1b4650507 100644
--- a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
+++ b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc
@@ -31,14 +31,46 @@
\section1 Scene Graph Adaptations in Qt Quick
-Originally Qt Quick only had one available renderer for parsing the
-scene graph and rendering the results to a render target. This renderer
-is now the default OpenGL Renderer which supports rendering either using
-the OpenGL ES 2.0 or OpenGL 2.0 APIs. The Qt Quick APIs are designed
-with the assumption that these two APIs are always available. It is
-however possible now to use other graphics API's to render Qt Quick
+Originally Qt Quick only had one available renderer for parsing the scene graph
+and rendering the results to a render target. This renderer is now the default
+OpenGL Renderer which supports rendering either using the OpenGL ES 2.0 or
+OpenGL 2.0 (with framebuffer object extensions) APIs. The Qt Quick APIs have
+originally been designed with the assumption that OpenGL is always available.
+However, it is now possible to use other graphics API's to render Qt Quick
scenes using the scene graph APIs.
+\section1 Switching between the adaptation used by the application
+
+The default of the OpenGL, or - in Qt builds with disabled OpenGL support - the
+software adaptation, can be overridden either by using an environment variable
+or a C++ API. The former consists of setting the \c{QT_QUICK_BACKEND} or the
+legacy \c{QMLSCENE_DEVICE} environment variable before launching applications.
+The latter is done by calling QQuickWindow::setSceneGraphBackend() early in the
+application's main() function.
+
+The supported backends are the following
+
+\list
+
+\li OpenGL - Requested by the string \c{""} or the enum value QSGRendererInterface::OpenGL.
+
+\li Software - Requested by the string \c{"software"} or the enum value QSGRendererInterface::Software.
+
+\li Direct3D 12 - Requested by the string \c{"d3d12"} or the enum value QSGRendererInterface::Direct3D12.
+
+\endlist
+
+When in doubt which backend is in use, enable basic scenegraph information
+logging via the \c{QSG_INFO} environment variable or the
+\c{qt.scenegraph.general} logging category. This will result in printing some
+information during application startup onto the debug output.
+
+\note Adaptations other than OpenGL will typically come with a set of
+limitations since they are unlikely to provide a feature set 100% compatible
+with OpenGL. However, they may provide their own specific advantages in certain
+areas. Refer to the sections below for more information on the various
+adaptations.
+
\section1 OpenGL ES 2.0 and OpenGL 2.0 Adaptation
The default adaptation capable of providing the full Qt Quick 2 feature
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
index eb0e26462a..26efba5b13 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
@@ -149,7 +149,7 @@ void QSGAbstractSoftwareRenderer::buildRenderList()
QSGSoftwareRenderListBuilder(this).visitChildren(rootNode());
}
-void QSGAbstractSoftwareRenderer::optimizeRenderList()
+QRegion QSGAbstractSoftwareRenderer::optimizeRenderList()
{
// Iterate through the renderlist from front to back
// Objective is to update the dirty status and rects.
@@ -212,9 +212,13 @@ void QSGAbstractSoftwareRenderer::optimizeRenderList()
m_dirtyRegion += node->dirtyRegion();
}
+ QRegion updateRegion = m_dirtyRegion;
+
// Empty dirtyRegion
m_dirtyRegion = QRegion();
m_obscuredRegion = QRegion();
+
+ return updateRegion;
}
void QSGAbstractSoftwareRenderer::setBackgroundColor(const QColor &color)
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
index a2e953f40d..73410b09f5 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer_p.h
@@ -78,7 +78,7 @@ public:
protected:
QRegion renderNodes(QPainter *painter);
void buildRenderList();
- void optimizeRenderList();
+ QRegion optimizeRenderList();
void setBackgroundColor(const QColor &color);
void setBackgroundSize(const QSize &size);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
index ea00de7a66..7bf06f8081 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
@@ -45,6 +45,7 @@
#include "qsgsoftwarerenderablenode_p.h"
#include <QtGui/QPaintDevice>
+#include <QtGui/QBackingStore>
#include <QElapsedTimer>
Q_LOGGING_CATEGORY(lcRenderer, "qt.scenegraph.softwarecontext.renderer")
@@ -53,6 +54,8 @@ QT_BEGIN_NAMESPACE
QSGSoftwareRenderer::QSGSoftwareRenderer(QSGRenderContext *context)
: QSGAbstractSoftwareRenderer(context)
+ , m_paintDevice(nullptr)
+ , m_backingStore(nullptr)
{
}
@@ -63,6 +66,13 @@ QSGSoftwareRenderer::~QSGSoftwareRenderer()
void QSGSoftwareRenderer::setCurrentPaintDevice(QPaintDevice *device)
{
m_paintDevice = device;
+ m_backingStore = nullptr;
+}
+
+void QSGSoftwareRenderer::setBackingStore(QBackingStore *backingStore)
+{
+ m_backingStore = backingStore;
+ m_paintDevice = nullptr;
}
QRegion QSGSoftwareRenderer::flushRegion() const
@@ -82,18 +92,19 @@ void QSGSoftwareRenderer::renderScene(uint)
void QSGSoftwareRenderer::render()
{
- if (!m_paintDevice)
+ if (!m_paintDevice && !m_backingStore)
return;
+ // If there is a backingstore, set the current paint device
+ if (m_backingStore)
+ m_paintDevice = m_backingStore->paintDevice();
+
QElapsedTimer renderTimer;
setBackgroundColor(clearColor());
setBackgroundSize(QSize(m_paintDevice->width() / m_paintDevice->devicePixelRatio(),
m_paintDevice->height() / m_paintDevice->devicePixelRatio()));
- QPainter painter(m_paintDevice);
- painter.setRenderHint(QPainter::Antialiasing);
-
// Build Renderlist
// The renderlist is created by visiting each node in the tree and when a
// renderable node is reach, we find the coorosponding RenderableNode object
@@ -113,13 +124,23 @@ void QSGSoftwareRenderer::render()
// side effect of this is that additional nodes may need to be marked dirty to
// force a repaint. It is also important that any item that needs to be
// repainted only paints what is needed, via the use of clip regions.
- optimizeRenderList();
+ const QRegion updateRegion = optimizeRenderList();
qint64 optimizeRenderListTime = renderTimer.restart();
+ // If Rendering to a backingstore, prepare it to be updated
+ if (m_backingStore != nullptr)
+ m_backingStore->beginPaint(updateRegion);
+
+ QPainter painter(m_paintDevice);
+ painter.setRenderHint(QPainter::Antialiasing);
+
// Render the contents Renderlist
m_flushRegion = renderNodes(&painter);
qint64 renderTime = renderTimer.elapsed();
+ if (m_backingStore != nullptr)
+ m_backingStore->endPaint();
+
qCDebug(lcRenderer) << "render" << m_flushRegion << buildRenderListTime << optimizeRenderListTime << renderTime;
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h
index e2b8bcddca..a201e4887e 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer_p.h
@@ -56,6 +56,7 @@
QT_BEGIN_NAMESPACE
class QPaintDevice;
+class QBackingStore;
class Q_QUICK_PRIVATE_EXPORT QSGSoftwareRenderer : public QSGAbstractSoftwareRenderer
{
@@ -64,6 +65,7 @@ public:
virtual ~QSGSoftwareRenderer();
void setCurrentPaintDevice(QPaintDevice *device);
+ void setBackingStore(QBackingStore *backingStore);
QRegion flushRegion() const;
protected:
@@ -72,6 +74,7 @@ protected:
private:
QPaintDevice* m_paintDevice;
+ QBackingStore* m_backingStore;
QRegion m_flushRegion;
};
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
index 5292e1371f..0b111c7b19 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
@@ -156,11 +156,9 @@ void QSGSoftwareRenderLoop::renderWindow(QQuickWindow *window)
//Tell the renderer about the windows backing store
auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(cd->renderer);
if (softwareRenderer)
- softwareRenderer->setCurrentPaintDevice(m_backingStores[window]->paintDevice());
+ softwareRenderer->setBackingStore(m_backingStores[window]);
- m_backingStores[window]->beginPaint(QRect(0, 0, window->width(), window->height()));
cd->renderSceneGraph(window->size());
- m_backingStores[window]->endPaint();
if (profileFrames)
renderTime = renderTimer.nsecsElapsed();