aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-05-04 09:28:23 +0200
committerLiang Qi <liang.qi@qt.io>2018-05-04 10:08:56 +0200
commit2044d0a03bafa4597863eb2bf3ecb8fa6731ed57 (patch)
tree5f2c0d44742770dfcc1dabf1efd8021b21cfeba4 /src
parent7b0cb855edcfdeb04e7d0d1c2545958877481ecc (diff)
parent717b57a9aae4c6d45cbcf91d390e42af56ab8061 (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts: src/qml/qml/qqmltypeloader.cpp src/qml/qml/qqmltypeloader_p.h Done-with: Simon Hausmann <simon.hausmann@qt.io> Task-number: QTBUG-68091 Change-Id: I7c0ab3c9446ac50da07b58f54e24eb4587f7f28c
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/qqmlcontext.cpp13
-rw-r--r--src/qml/qml/qqmlcontext_p.h5
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp28
-rw-r--r--src/qml/qml/qqmltypeloader_p.h6
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp7
-rw-r--r--src/qmldebug/qqmlprofilerclientdefinitions_p.h11
-rw-r--r--src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc1
-rw-r--r--src/quick/items/qquickitem.cpp6
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp11
10 files changed, 68 insertions, 24 deletions
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 5dd3278b4c..3dcfa92416 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -536,7 +536,7 @@ QQmlContextData::QQmlContextData()
QQmlContextData::QQmlContextData(QQmlContext *ctxt)
: engine(nullptr), isInternal(false), isJSContext(false),
isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false),
- publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1),
+ stronglyReferencedByParent(false), publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1),
contextObject(nullptr), nextChild(nullptr), prevChild(nullptr),
expressions(nullptr), contextObjects(nullptr), idValues(nullptr), idValueCount(0),
componentAttached(nullptr)
@@ -577,7 +577,10 @@ void QQmlContextData::invalidate()
while (childContexts) {
Q_ASSERT(childContexts != this);
- childContexts->invalidate();
+ if (childContexts->stronglyReferencedByParent && !--childContexts->refCount)
+ childContexts->destroy();
+ else
+ childContexts->invalidate();
}
if (prevChild) {
@@ -672,12 +675,16 @@ void QQmlContextData::destroy()
delete this;
}
-void QQmlContextData::setParent(QQmlContextData *p)
+void QQmlContextData::setParent(QQmlContextData *p, bool stronglyReferencedByParent)
{
if (p == parent)
return;
if (p) {
+ Q_ASSERT(!parent);
parent = p;
+ this->stronglyReferencedByParent = stronglyReferencedByParent;
+ if (stronglyReferencedByParent)
+ ++refCount; // balanced in QQmlContextData::invalidate()
engine = p->engine;
nextChild = p->childContexts;
if (nextChild) nextChild->prevChild = &nextChild;
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index 5dfee48848..290b7fc7ee 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -126,7 +126,7 @@ public:
QQmlContextData *parent = nullptr;
QQmlEngine *engine;
- void setParent(QQmlContextData *);
+ void setParent(QQmlContextData *, bool stronglyReferencedByParent = false);
void refreshExpressions();
void addObject(QObject *);
@@ -144,7 +144,8 @@ public:
quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name
quint32 hasEmittedDestruction:1;
quint32 isRootObjectInCreation:1;
- quint32 dummy:26;
+ quint32 stronglyReferencedByParent:1;
+ quint32 dummy:25;
QQmlContext *publicContext;
// The incubator that is constructing this context if any
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 6429e06070..60617630d2 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1217,9 +1217,9 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
}
ddata = QQmlData::get(instance, /*create*/true);
- ddata->lineNumber = obj->location.line;
- ddata->columnNumber = obj->location.column;
}
+ ddata->lineNumber = obj->location.line;
+ ddata->columnNumber = obj->location.column;
ddata->setImplicitDestructible();
if (static_cast<quint32>(index) == /*root object*/0 || ddata->rootObjectInCreation) {
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 29ca10714f..e295c055e7 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1641,14 +1641,24 @@ QQmlImportDatabase *QQmlTypeLoader::importDatabase() const
return &QQmlEnginePrivate::get(engine())->importDatabase;
}
+QUrl QQmlTypeLoader::normalize(const QUrl &unNormalizedUrl)
+{
+ QUrl normalized(unNormalizedUrl);
+ if (normalized.scheme() == QLatin1String("qrc"))
+ normalized.setHost(QString()); // map qrc:///a.qml to qrc:/a.qml
+ return normalized;
+}
+
/*!
Returns a QQmlTypeData for the specified \a url. The QQmlTypeData may be cached.
*/
-QQmlRefPointer<QQmlTypeData> QQmlTypeLoader::getType(const QUrl &url, Mode mode)
+QQmlRefPointer<QQmlTypeData> QQmlTypeLoader::getType(const QUrl &unNormalizedUrl, Mode mode)
{
- Q_ASSERT(!url.isRelative() &&
- (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() ||
- !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url))));
+ Q_ASSERT(!unNormalizedUrl.isRelative() &&
+ (QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl).isEmpty() ||
+ !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl))));
+
+ QUrl url = normalize(unNormalizedUrl);
LockHolder<QQmlTypeLoader> holder(this);
@@ -1705,11 +1715,13 @@ QQmlRefPointer<QQmlTypeData> QQmlTypeLoader::getType(const QByteArray &data, con
/*!
Return a QQmlScriptBlob for \a url. The QQmlScriptData may be cached.
*/
-QQmlRefPointer<QQmlScriptBlob> QQmlTypeLoader::getScript(const QUrl &url)
+QQmlRefPointer<QQmlScriptBlob> QQmlTypeLoader::getScript(const QUrl &unNormalizedUrl)
{
- Q_ASSERT(!url.isRelative() &&
- (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() ||
- !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url))));
+ Q_ASSERT(!unNormalizedUrl.isRelative() &&
+ (QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl).isEmpty() ||
+ !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl))));
+
+ QUrl url = normalize(unNormalizedUrl);
LockHolder<QQmlTypeLoader> holder(this);
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 66b1eaf18e..98ac4b1bc1 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -304,10 +304,12 @@ public:
QQmlImportDatabase *importDatabase() const;
- QQmlRefPointer<QQmlTypeData> getType(const QUrl &url, Mode mode = PreferSynchronous);
+ static QUrl normalize(const QUrl &unNormalizedUrl);
+
+ QQmlRefPointer<QQmlTypeData> getType(const QUrl &unNormalizedUrl, Mode mode = PreferSynchronous);
QQmlRefPointer<QQmlTypeData> getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous);
- QQmlRefPointer<QQmlScriptBlob> getScript(const QUrl &);
+ QQmlRefPointer<QQmlScriptBlob> getScript(const QUrl &unNormalizedUrl);
QQmlRefPointer<QQmlQmldirData> getQmldir(const QUrl &);
QString absoluteFilePath(const QString &path);
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 2cfb740ebf..3863f9e968 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -903,10 +903,11 @@ void QQmlDelegateModelPrivate::removeCacheItem(QQmlDelegateModelItem *cacheItem)
void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status)
{
- Q_Q(QQmlDelegateModel);
if (!isDoneIncubating(status))
return;
+ const QList<QQmlError> incubationTaskErrors = incubationTask->errors();
+
QQmlDelegateModelItem *cacheItem = incubationTask->incubating;
cacheItem->incubationTask = nullptr;
incubationTask->incubating = nullptr;
@@ -920,7 +921,7 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba
emitCreatedItem(incubationTask, cacheItem->object);
cacheItem->releaseObject();
} else if (status == QQmlIncubator::Error) {
- qmlWarning(q, m_delegate->errors()) << "Error creating delegate";
+ qmlWarning(m_delegate, incubationTaskErrors + m_delegate->errors()) << "Error creating delegate";
}
if (!cacheItem->isObjectReferenced()) {
@@ -1017,7 +1018,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ
if (QQmlAdaptorModelProxyInterface *proxy
= qobject_cast<QQmlAdaptorModelProxyInterface *>(cacheItem)) {
ctxt = new QQmlContextData;
- ctxt->setParent(cacheItem->contextData);
+ ctxt->setParent(cacheItem->contextData, /*stronglyReferencedByParent*/true);
ctxt->contextObject = proxy->proxiedObject();
}
}
diff --git a/src/qmldebug/qqmlprofilerclientdefinitions_p.h b/src/qmldebug/qqmlprofilerclientdefinitions_p.h
index c8524574f6..be1c6318af 100644
--- a/src/qmldebug/qqmlprofilerclientdefinitions_p.h
+++ b/src/qmldebug/qqmlprofilerclientdefinitions_p.h
@@ -40,6 +40,17 @@
#ifndef QQMLPROFILERCLIENTDEFINITIONS_P_H
#define QQMLPROFILERCLIENTDEFINITIONS_P_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 <QtCore/qglobal.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
index e70791d1c9..b22b013684 100644
--- a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
+++ b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
@@ -29,6 +29,7 @@
\page qtquick-bestpractices.html
\title Best Practices for QML and Qt Quick
\brief Lists best practices for working with QML and Qt Quick
+\ingroup best-practices
Despite all of the benefits that QML and Qt Quick offer, they can be
challenging in certain situations. The following sections elaborate on some of
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 23d9cc1219..f02ad24c5b 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -3134,6 +3134,9 @@ void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
*/
QTransform QQuickItemPrivate::windowToGlobalTransform() const
{
+ if (Q_UNLIKELY(window == nullptr))
+ return QTransform();
+
QPoint quickWidgetOffset;
QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window, &quickWidgetOffset);
QPointF pos = (renderWindow ? renderWindow : window)->mapToGlobal(quickWidgetOffset);
@@ -3145,6 +3148,9 @@ QTransform QQuickItemPrivate::windowToGlobalTransform() const
*/
QTransform QQuickItemPrivate::globalToWindowTransform() const
{
+ if (Q_UNLIKELY(window == nullptr))
+ return QTransform();
+
QPoint quickWidgetOffset;
QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window, &quickWidgetOffset);
QPointF pos = (renderWindow ? renderWindow : window)->mapToGlobal(quickWidgetOffset);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
index aa83709b72..74426c5c4d 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
@@ -68,6 +68,9 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
QMargins sourceMargins = normalizedMargins(sourceMarginsIn);
QMargins targetMargins = normalizedMargins(targetMarginsIn);
+ const qreal sourceDpr = pixmap.devicePixelRatioF();
+ sourceMargins *= sourceDpr;
+
// source center
const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
const int sourceCenterLeft = sourceRect.left() + sourceMargins.left();
@@ -89,9 +92,9 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
int columns = 3;
int rows = 3;
if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0)
- columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth)));
+ columns = qMax(3, 2 + qCeil((targetCenterWidth * sourceDpr) / qreal(sourceCenterWidth)));
if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0)
- rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight)));
+ rows = qMax(3, 2 + qCeil((targetCenterHeight * sourceDpr) / qreal(sourceCenterHeight)));
xTarget.resize(columns + 1);
yTarget.resize(rows + 1);
@@ -121,7 +124,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
dx = targetCenterWidth;
break;
case Qt::RepeatTile:
- dx = sourceCenterWidth;
+ dx = sourceCenterWidth / sourceDpr;
break;
case Qt::RoundTile:
dx = targetCenterWidth / qreal(columns - 2);
@@ -136,7 +139,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
dy = targetCenterHeight;
break;
case Qt::RepeatTile:
- dy = sourceCenterHeight;
+ dy = sourceCenterHeight / sourceDpr;
break;
case Qt::RoundTile:
dy = targetCenterHeight / qreal(rows - 2);