From 306843e180207665c88de22165cf96b3d5450f42 Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Fri, 24 May 2019 18:02:54 +0200 Subject: QQuickWidget: fix missing update on show event for software renderer The triggerUpdate call was incorrectly removed by merge 42f485231c Fixes: QTBUG-68566 Change-Id: Ibf37d88315d3ef9879e6cb9728a1c4ef4655c72b Reviewed-by: Michal Klocek --- src/quickwidgets/qquickwidget.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index f1a0f0c863..b63f7de9f1 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -1314,9 +1314,13 @@ void QQuickWidget::mouseDoubleClickEvent(QMouseEvent *e) void QQuickWidget::showEvent(QShowEvent *) { Q_D(QQuickWidget); + bool shouldTriggerUpdate = true; + if (!d->useSoftwareRenderer) { d->createContext(); + if (d->offscreenWindow->openglContext()) { + shouldTriggerUpdate = false; d->render(true); // render() may have led to a QQuickWindow::update() call (for // example, having a scene with a QQuickFramebufferObject::Renderer @@ -1329,11 +1333,12 @@ void QQuickWidget::showEvent(QShowEvent *) d->updatePending = false; update(); } - } else { - triggerUpdate(); } } + if (shouldTriggerUpdate) + triggerUpdate(); + // note offscreenWindow is "QQuickOffScreenWindow" instance d->offscreenWindow->setVisible(true); if (QQmlInspectorService *service = QQmlDebugConnector::service()) -- cgit v1.2.3 From 677af8c7e8d4b7627cb4b8227c3cd869aba577ef Mon Sep 17 00:00:00 2001 From: Jason Duerstock Date: Tue, 28 May 2019 11:58:38 -0400 Subject: Add a workaround for ia64 to move Value bits 63-61 to 49-47 for pointers Task-number: QTBUG-56264 Change-Id: Ifdede70d95f5846e160772c43d22bc2a4123959b Reviewed-by: Thiago Macieira --- src/qml/jsruntime/qv4value_p.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src') diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index b4a045edfb..ce85e48b72 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -146,12 +146,29 @@ struct Q_QML_PRIVATE_EXPORT Value QML_NEARLY_ALWAYS_INLINE Heap::Base *m() const { Heap::Base *b; +#ifdef __ia64 +// Restore bits 49-47 to bits 63-61, undoing the workaround explained in +// setM below. + quint64 _tmp; + + _tmp = _val & (7L << 47); // 0x3800000000000 + _tmp = (_tmp << 14) | (_val ^ _tmp); + memcpy(&b, &_tmp, 8); +#else memcpy(&b, &_val, 8); +#endif return b; } QML_NEARLY_ALWAYS_INLINE void setM(Heap::Base *b) { memcpy(&_val, &b, 8); +#ifdef __ia64 +// On ia64, bits 63-61 in a 64-bit pointer are used to store the virtual region +// number. Since this implementation is not 64-bit clean, we move bits 63-61 +// to bits 49-47 and hope for the best. This is undone in *m(), above. + _val |= ((_val & (7L << 61)) >> 14); + _val &= ((1L << 50)-1); +#endif } #elif QT_POINTER_SIZE == 4 QML_NEARLY_ALWAYS_INLINE Heap::Base *m() const -- cgit v1.2.3 From 2ae68e243e3177220edd8b305116db92046c7c2c Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 29 May 2019 14:51:17 +0200 Subject: In qmlUnregisterType() also remove the type from undeletableTypes Task-number: QTBUG-76074 Change-Id: I7f5ca6af0955524f9a417811c2e9f960c2b3efb3 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlmetatype.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index c0628c3523..573288b77f 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -2572,7 +2572,8 @@ void qmlUnregisterType(int typeIndex) QMutexLocker lock(metaTypeDataLock()); QQmlMetaTypeData *data = metaTypeData(); { - const QQmlTypePrivate *d = data->types.value(typeIndex).priv(); + const QQmlType type = data->types.value(typeIndex); + const QQmlTypePrivate *d = type.priv(); if (d) { removeQQmlTypePrivate(data->idToType, d); removeQQmlTypePrivate(data->nameToType, d); @@ -2584,6 +2585,7 @@ void qmlUnregisterType(int typeIndex) modulePrivate->remove(d); } data->types[typeIndex] = QQmlType(); + data->undeletableTypes.remove(type); } } } -- cgit v1.2.3 From fefbb353dd9047cb6c88ca518a2335269111a049 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 23 Jan 2019 12:44:17 +0100 Subject: Doc: Fix incorrect snippet in Repeater QML type documentation Task-number: QTBUG-73199 Change-Id: I83f0754577b382b26f484bfdc4f6b3a2a921b5f1 Reviewed-by: Paul Wicking --- src/quick/items/qquickrepeater.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index 805b6fe190..0c00fecead 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -121,16 +121,17 @@ QQuickRepeaterPrivate::~QQuickRepeaterPrivate() Also, note that Repeater is \l {Item}-based, and can only repeat \l {Item}-derived objects. For example, it cannot be used to repeat QtObjects: - \code - //bad code + + \qml + // bad code: Item { - Can't repeat QtObject as it doesn't derive from Item. + // Can't repeat QtObject as it doesn't derive from Item. Repeater { model: 10 QtObject {} } } - \endcode + \endqml */ /*! -- cgit v1.2.3 From acc3d31f7069a244c32fca01f8a2873e0798c785 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 15 May 2019 13:54:31 +0200 Subject: Fix assert in QSGBasicInternalImageNode::updateGeometry Handle that hCells and vCells might be 0 with non-0 innerTarget. Fixes: QTBUG-73768 Change-Id: Id9dde2368e8cdfe40e5b287b16c0473ad7c12d69 Reviewed-by: Robin Burchell --- src/quick/scenegraph/qsgbasicinternalimagenode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/quick/scenegraph/qsgbasicinternalimagenode.cpp b/src/quick/scenegraph/qsgbasicinternalimagenode.cpp index c434563c90..d8efda1ecc 100644 --- a/src/quick/scenegraph/qsgbasicinternalimagenode.cpp +++ b/src/quick/scenegraph/qsgbasicinternalimagenode.cpp @@ -258,7 +258,7 @@ QSGGeometry *QSGBasicInternalImageNode::updateGeometry(const QRectF &targetRect, xs[1].tx = innerSourceRect.left(); xs += 2; } - if (innerTargetRect.width() != 0) { + if (innerTargetRect.width() != 0 && hTiles > 0) { xs[0].x = innerTargetRect.left(); xs[0].tx = innerSourceRect.x() + (subSourceRect.left() - floorLeft) * innerSourceRect.width(); ++xs; @@ -299,7 +299,7 @@ QSGGeometry *QSGBasicInternalImageNode::updateGeometry(const QRectF &targetRect, ys[1].ty = innerSourceRect.top(); ys += 2; } - if (innerTargetRect.height() != 0) { + if (innerTargetRect.height() != 0 && vTiles > 0) { ys[0].y = innerTargetRect.top(); ys[0].ty = innerSourceRect.y() + (subSourceRect.top() - floorTop) * innerSourceRect.height(); ++ys; -- cgit v1.2.3 From 1ee7afa50fe5fe995008dee5d00638b894145d12 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 16 May 2019 14:15:06 +0200 Subject: Re-add cache for looking up attached properties objects c018df5b4075ae962966d4df7653d476dab02840 removed an optimization in qmlAttachedPropertiesObject. The attached properties ID was implicitly cached as it was static in a method templated by the type the attached properties were registered for. We don't actually need the ID for this, as we can also cache the function pointer. Fixes: QTBUG-75609 Change-Id: I15e728ce4bbb89062a84ee6f113b1188faa32b92 Reviewed-by: Simon Hausmann --- src/qml/qml/qqml.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index 9eacc5bc22..ebf4817b4a 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -605,9 +605,12 @@ Q_QML_EXPORT void qmlRegisterModule(const char *uri, int versionMajor, int versi template QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true) { - QObject *mutableObj = const_cast(obj); - return qmlAttachedPropertiesObject( - mutableObj, qmlAttachedPropertiesFunction(mutableObj, &T::staticMetaObject), create); + // We don't need a concrete object to resolve the function. As T is a C++ type, it and all its + // super types should be registered as CppType (or not at all). We only need the object and its + // QML engine to resolve composite types. Therefore, the function is actually a static property + // of the C++ type system and we can cache it here for improved performance on further lookups. + static const auto func = qmlAttachedPropertiesFunction(nullptr, &T::staticMetaObject); + return qmlAttachedPropertiesObject(const_cast(obj), func, create); } Q_QML_EXPORT void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor); -- cgit v1.2.3 From 869b89bde8b0149a875e6e23466820f573e4a73c Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 13 May 2019 14:13:34 +0200 Subject: Print a warning when encountering a non-relative URL in a qmldir file This is not supported because supporting it would encourage users to create components that won't work on other systems or that will confuse qmlplugindump. QML still parses and loads those components, but you should really use relative paths. Task-number: QTBUG-48809 Change-Id: I9c81671cb5c4ea59b8c884ff24ad02e82047e9d6 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmldirparser_p.h | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqmldirparser_p.h b/src/qml/qml/qqmldirparser_p.h index d7e29813d1..bfb75d0509 100644 --- a/src/qml/qml/qqmldirparser_p.h +++ b/src/qml/qml/qqmldirparser_p.h @@ -76,12 +76,24 @@ public: QString typeNamespace() const; void setTypeNamespace(const QString &s); + static void checkNonRelative(const char *item, const QString &typeName, const QString &fileName) + { + if (fileName.startsWith(QLatin1Char('/')) || fileName.contains(QLatin1Char(':'))) { + qWarning() << item << typeName + << "is specified with non-relative URL" << fileName << "in a qmldir file." + << "URLs in qmldir files should be relative to the qmldir file's directory."; + } + } + struct Plugin { Plugin() {} Plugin(const QString &name, const QString &path) - : name(name), path(path) {} + : name(name), path(path) + { + checkNonRelative("Plugin", name, path); + } QString name; QString path; @@ -93,7 +105,10 @@ public: Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion) : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion), - internal(false), singleton(false) {} + internal(false), singleton(false) + { + checkNonRelative("Component", typeName, fileName); + } QString typeName; QString fileName; @@ -108,7 +123,10 @@ public: Script() {} Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion) - : nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) {} + : nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) + { + checkNonRelative("Script", nameSpace, fileName); + } QString nameSpace; QString fileName; -- cgit v1.2.3 From c61a75cd6a4a9cd7b3594b205fcac8fc1208d493 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 15 Mar 2019 11:13:05 +0100 Subject: Fix leaking scene graph rendering contexts When using the threaded render loop, the rendering thread assumes ownership of the rendering context. If the rendering thread is never started, that context is leaked. This happens in tests sometimes when we create and destroy a window without waiting for exposure. So this patch maintains the ownership in the render loop for created contexts until the per-window thread is started. Task-number: QTBUG-74348 Change-Id: Ifa397fab0833c82110ac4571c1e3790351c43afd Reviewed-by: BogDan Vatra Reviewed-by: Ulf Hermann --- src/quick/scenegraph/qsgthreadedrenderloop.cpp | 10 ++++++++-- src/quick/scenegraph/qsgthreadedrenderloop_p.h | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index c18ba4226c..232ef77324 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -770,12 +770,15 @@ QSGThreadedRenderLoop::QSGThreadedRenderLoop() QSGThreadedRenderLoop::~QSGThreadedRenderLoop() { + qDeleteAll(pendingRenderContexts); delete sg; } QSGRenderContext *QSGThreadedRenderLoop::createRenderContext(QSGContext *sg) const { - return sg->createRenderContext(); + auto context = sg->createRenderContext(); + pendingRenderContexts.insert(context); + return context; } void QSGThreadedRenderLoop::maybePostPolishRequest(Window *w) @@ -935,7 +938,10 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window) Window win; win.window = window; win.actualWindowFormat = window->format(); - win.thread = new QSGRenderThread(this, QQuickWindowPrivate::get(window)->context); + auto renderContext = QQuickWindowPrivate::get(window)->context; + // The thread assumes ownership, so we don't need to delete it later. + pendingRenderContexts.remove(renderContext); + win.thread = new QSGRenderThread(this, renderContext); win.updateDuringSync = false; win.forceRenderPass = true; // also covered by polishAndSync(inExpose=true), but doesn't hurt m_windows << win; diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h index 32bfcb7148..b8fae8e8da 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h +++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h @@ -124,6 +124,9 @@ private: QSGContext *sg; + // Set of contexts that have been created but are now owned by + // a rendering thread yet, as the window has never been exposed. + mutable QSet pendingRenderContexts; QAnimationDriver *m_animation_driver; QList m_windows; -- cgit v1.2.3 From 2f4479857d2b68f8cd3267b2f2b3c652ada431ed Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 20 May 2019 16:09:13 +0200 Subject: Fix lookups of properties in QML singletons An unqualified name that points to a QML singleton will evaluate to a QQmlTypeWrapper JS object. A member lookup in such an object is not guaranteed to always produce the same property. The property cache check may protect us from that, but we must still retrieve the QObject singleton for every lookup. Task-number: QTBUG-75896 Change-Id: Ibd9bac6e5c2047f838758811790b299ace636446 Reviewed-by: Ulf Hermann --- src/qml/jsruntime/qv4lookup_p.h | 2 +- src/qml/jsruntime/qv4qmlcontext.cpp | 2 -- src/qml/jsruntime/qv4qobjectwrapper.cpp | 1 - src/qml/jsruntime/qv4qobjectwrapper_p.h | 3 +-- src/qml/qml/qqmltypewrapper.cpp | 47 +++++++++++++++++++++++++++++---- src/qml/qml/qqmltypewrapper_p.h | 2 ++ 6 files changed, 46 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index 03dc5f6d3c..4fd5e133f7 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -120,7 +120,7 @@ struct Lookup { } indexedLookup; struct { Heap::InternalClass *ic; - Heap::QObjectWrapper *staticQObject; + Heap::InternalClass *qmlTypeIc; // only used when lookup goes through QQmlTypeWrapper QQmlPropertyCache *propertyCache; QQmlPropertyData *propertyData; } qobjectLookup; diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index 0c5226d46c..6aa0130188 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -293,7 +293,6 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r ScopedValue val(scope, base ? *base : Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, scopeObject))); const QObjectWrapper *That = static_cast(val->objectValue()); lookup->qobjectLookup.ic = That->internalClass(); - lookup->qobjectLookup.staticQObject = nullptr; lookup->qobjectLookup.propertyCache = ddata->propertyCache; lookup->qobjectLookup.propertyCache->addref(); lookup->qobjectLookup.propertyData = propertyData; @@ -326,7 +325,6 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r ScopedValue val(scope, base ? *base : Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, context->contextObject))); const QObjectWrapper *That = static_cast(val->objectValue()); lookup->qobjectLookup.ic = That->internalClass(); - lookup->qobjectLookup.staticQObject = nullptr; lookup->qobjectLookup.propertyCache = ddata->propertyCache; lookup->qobjectLookup.propertyCache->addref(); lookup->qobjectLookup.propertyData = propertyData; diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 6fed538fa8..63b6435112 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -870,7 +870,6 @@ ReturnedValue QObjectWrapper::virtualResolveLookupGetter(const Object *object, E } lookup->qobjectLookup.ic = This->internalClass(); - lookup->qobjectLookup.staticQObject = nullptr; lookup->qobjectLookup.propertyCache = ddata->propertyCache; lookup->qobjectLookup.propertyCache->addref(); lookup->qobjectLookup.propertyData = property; diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 2558ede401..5543c4d5a6 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -233,8 +233,7 @@ inline ReturnedValue QObjectWrapper::lookupGetterImpl(Lookup *lookup, ExecutionE if (!o || o->internalClass != lookup->qobjectLookup.ic) return revertLookup(); - const Heap::QObjectWrapper *This = lookup->qobjectLookup.staticQObject ? lookup->qobjectLookup.staticQObject : - static_cast(o); + const Heap::QObjectWrapper *This = static_cast(o); QObject *qobj = This->object(); if (QQmlData::wasDeleted(qobj)) return QV4::Encode::undefined(); diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 24c5aecc00..c5fa4a04ec 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -459,16 +459,16 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object, if (!includeEnums || !name->startsWithUpper()) { QQmlData *ddata = QQmlData::get(qobjectSingleton, false); if (ddata && ddata->propertyCache) { - ScopedValue val(scope, Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, qobjectSingleton))); QQmlPropertyData *property = ddata->propertyCache->property(name.getPointer(), qobjectSingleton, qmlContext); if (property) { - lookup->qobjectLookup.ic = This->internalClass(); - lookup->qobjectLookup.staticQObject = static_cast(val->heapObject()); + ScopedValue val(scope, Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, qobjectSingleton))); + lookup->qobjectLookup.qmlTypeIc = This->internalClass(); + lookup->qobjectLookup.ic = val->objectValue()->internalClass(); lookup->qobjectLookup.propertyCache = ddata->propertyCache; lookup->qobjectLookup.propertyCache->addref(); lookup->qobjectLookup.propertyData = property; - lookup->getter = QV4::QObjectWrapper::lookupGetter; - return lookup->getter(lookup, engine, *This); + lookup->getter = QQmlTypeWrapper::lookupSingletonProperty; + return lookup->getter(lookup, engine, *object); } // Fall through to base implementation } @@ -488,6 +488,43 @@ bool QQmlTypeWrapper::virtualResolveLookupSetter(Object *object, ExecutionEngine return Object::virtualResolveLookupSetter(object, engine, lookup, value); } +ReturnedValue QQmlTypeWrapper::lookupSingletonProperty(Lookup *l, ExecutionEngine *engine, const Value &object) +{ + const auto revertLookup = [l, engine, &object]() { + l->qobjectLookup.propertyCache->release(); + l->qobjectLookup.propertyCache = nullptr; + l->getter = Lookup::getterGeneric; + return Lookup::getterGeneric(l, engine, object); + }; + + // we can safely cast to a QV4::Object here. If object is something else, + // the internal class won't match + Heap::Object *o = static_cast(object.heapObject()); + if (!o || o->internalClass != l->qobjectLookup.qmlTypeIc) + return revertLookup(); + + Heap::QQmlTypeWrapper *This = static_cast(o); + + QQmlType type = This->type(); + if (!type.isValid()) + return revertLookup(); + + if (!type.isSingleton()) + return revertLookup(); + + QQmlEngine *e = engine->qmlEngine(); + QQmlType::SingletonInstanceInfo *siinfo = type.singletonInstanceInfo(); + siinfo->init(e); + + QObject *qobjectSingleton = siinfo->qobjectApi(e); + if (!qobjectSingleton) + return revertLookup(); + + Scope scope(engine); + ScopedValue obj(scope, QV4::QObjectWrapper::wrap(engine, qobjectSingleton)); + return QObjectWrapper::lookupGetterImpl(l, engine, obj, /*useOriginalProperty*/ true, revertLookup); +} + void Heap::QQmlScopedEnumWrapper::destroy() { QQmlType::derefHandle(typePrivate); diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 44e82dec2b..5f3cb2523f 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -114,6 +114,8 @@ struct Q_QML_EXPORT QQmlTypeWrapper : Object static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup); static bool virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value); + static ReturnedValue lookupSingletonProperty(Lookup *l, ExecutionEngine *engine, const Value &base); + protected: static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty); static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver); -- cgit v1.2.3 From 9e919489c4e6b0c110281fda139fff84c1c71995 Mon Sep 17 00:00:00 2001 From: Kavindra Palaraja Date: Tue, 21 May 2019 16:05:08 +0200 Subject: Doc - minor cleanup * Small fixes to improve readability * Fixed some typos * Updated the link to an old-ish MSDN article * Used a list instead of a long paragraph in the introduction area * Swapped a long list for a table for environment variables Change-Id: Id7eeee5c5b24f96e4577212a385cfa766e809d1f Reviewed-by: Simon Hausmann --- .../doc/src/concepts/visualcanvas/adaptations.qdoc | 588 ++++++++++----------- 1 file changed, 281 insertions(+), 307 deletions(-) (limited to 'src') diff --git a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc index b0e45fadae..8edc5cb0b6 100644 --- a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc +++ b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc @@ -31,72 +31,68 @@ \section1 Scene Graph Adaptations in Qt Quick -Originally Qt Quick always relied on OpenGL (OpenGL ES 2.0 or OpenGL 2.0) for parsing -the scene graph and rendering the results to a render target. From Qt 5.8 onwards -Qt Quick also supports rendering in software and with Direct3D 12. +Originally, Qt Quick always relied on OpenGL (OpenGL ES 2.0 or OpenGL 2.0) to parse the scene graph +and render the results to a render target. From Qt 5.8 onwards, Qt Quick also supports rendering in +software and with Direct3D 12. -\section1 Switching Between the Adaptation Used by the Application +\target Switching Between the Adaptation Used by the Application +\section1 Switch Between Adaptations in Your Application -The default rendering backend is still OpenGL, or - in Qt builds with disabled OpenGL support - -the software renderer. This 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 +The default rendering backend is still OpenGL, but in Qt builds with OpenGL support disabled, the +default is the software renderer. You can override this in one of two ways: \list + \li Use an environment variable - Set the \c{QT_QUICK_BACKEND} or the legacy + \c{QMLSCENE_DEVICE} environment variable before launching applications. + \li Use a C++ API - Call QQuickWindow::setSceneGraphBackend() early on in the application's + main() function. +\endlist -\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. - -\li OpenVG - Requested by the string \c{"openvg"} or the enum value QSGRendererInterface::OpenVG. +The following backends are supported: +\list + \li OpenGL - Request with the \c{""} string or the QSGRendererInterface::OpenGL enum value. + \li Software - Request with the \c{"software"} string or the QSGRendererInterface::Software + enum value. + \li Direct3D 12 - Request with the \c{"d3d12"} string or the QSGRendererInterface::Direct3D12 + enum value. + \li OpenVG - Request with the \c{"openvg"} string or the QSGRendererInterface::OpenVG enum + value. \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. +To find out which backend is in use, you can enable basic scene graph information logging via the +\c{QSG_INFO} environment variable or the \c{qt.scenegraph.general} logging category. This results +in some information being printed onto the debug output, during application startup. -\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. +\note Typically, adaptations other than OpenGL come with a set of limitations as they are unlikely + to provide a feature set that's 100% compatible with OpenGL. However, these adaptations may + provide their own specific advantages in certain areas. For more information on the various + adaptations, refer to the sections below. \section1 OpenGL ES 2.0 and OpenGL 2.0 Adaptation -The default adaptation capable of providing the full Qt Quick 2 feature -set is the OpenGL adaptation. All of the details of the OpenGL -adaptation can are available here: -\l{qtquick-visualcanvas-scenegraph-renderer.html}{OpenGL Adaptation} +The OpenGL adaptation is the default adaptation, which is capable of providing the full Qt Quick 2 +feature set. For more details, see +\l{qtquick-visualcanvas-scenegraph-renderer.html}{OpenGL Adaptation}. \section1 Software Adaptation -The Software adaptation is an alternative renderer for \l {Qt Quick} 2 that -uses the raster paint engine to render the contents of the scene graph. The -details for this adaptation are available here: -\l{qtquick-visualcanvas-adaptations-software.html}{Software Adaptation} +The Software adaptation is an alternative renderer for \l{Qt Quick} 2 that uses the raster paint +engine to render the contents of the scene graph. For more details, see +\l{qtquick-visualcanvas-adaptations-software.html}{Software Adaptation}. \section1 Direct3D 12 (experimental) -The Direct3D 12 adaptation is an alternative renderer for \l {Qt Quick} 2 when -running on Windows 10, both for Win32 and UWP applications. The details for -this adaptation are available here: -\l{qtquick-visualcanvas-adaptations-d3d12.html}{Direct3D 12 Adaptation} +The Direct3D 12 adaptation is an alternative renderer for \l{Qt Quick} 2 when running on Windows +10, both for Win32 and UWP applications. For more details, see +\l{qtquick-visualcanvas-adaptations-d3d12.html}{Direct3D 12 Adaptation}. \section1 OpenVG -The OpenVG adaptation is an alternative renderer for \l {Qt Quick} 2 that will -renderer the contents of the scene graph using OpenVG commands to provide -hardware-acclerated 2D vector and raster graphics. The details for this -adaptation are available here: -\l{qtquick-visualcanvas-adaptations-openvg.html}{OpenVG Adaptation} +The OpenVG adaptation is an alternative renderer for \l{Qt Quick} 2 that renders the contents of +the scene graph using OpenVG commands to provide hardware-accelerated 2D vector and raster +graphics. For more details, see +\l{qtquick-visualcanvas-adaptations-openvg.html}{OpenVG Adaptation}. */ @@ -104,47 +100,44 @@ adaptation are available here: \title Qt Quick Software Adaptation \page qtquick-visualcanvas-adaptations-software.html -The Software adaptation is an alternative renderer for \l {Qt Quick} 2 that -uses the Raster paint engine to render the contents of the scene graph instead -of OpenGL. As a result of not using OpenGL to render the scene graph, some -features and optimizations are no longer available. Most Qt Quick 2 -applications will run without modification though any attempts to use -unsupported features will be ignored. By using the Software adaptation it is -possible to run Qt Quick 2 applications on hardware and platforms that do not -have OpenGL support. - -The Software adaptation was previously known as the Qt Quick 2D Renderer. -However, unlike the 2D Renderer, the new, integrated version supports partial -updates. This means that the full update of the window or screen contents is -now avoided, and only the changed areas get flushed. This can significantly -improve performance for many applications. +The Software adaptation is an alternative renderer for \l {Qt Quick} 2 that uses the Raster paint +engine to render the contents of the scene graph, instead of OpenGL. Consequently, some features +and optimizations are not available. Most Qt Quick 2 applications can run without any modification, +but any attempts to use unsupported features are ignored. By using the Software adaptation, it is +possible to run Qt Quick 2 applications on hardware and platforms that do not have OpenGL support. + +The Software adaptation was previously known as the Qt Quick 2D Renderer. However, unlike the 2D +Renderer, this new, integrated version supports partial updates. This means that a full update +of the window or screen contents is now avoided; only the changed areas are flushed. Partial +updates can significantly improve performance for many applications. \section2 Shader Effects -ShaderEffect components in QtQuick 2 can not be rendered by the Software adptation. + +ShaderEffect components in QtQuick 2 cannot be rendered by the Software adaptation. \section2 Qt Graphical Effects Module -\l {Qt Graphical Effects} uses ShaderEffect items to render effects. If you use -graphical effects from this module, then you should not hide the source -item so that the original item can still be rendered. + +\l {Qt Graphical Effects} uses ShaderEffect items to render effects. If you use graphical effects +from this module, then you should not hide the source item so that the original item can still be +rendered. \section2 Particle Effects -It is not possible to render particle effects with the Software adaptation. Whenever -possible, remove particles completely from the scene. Otherwise they will still -require some processing, even though they are not visible. + +It is not possible to render particle effects with the Software adaptation. Whenever possible, +remove particles completely from the scene. Otherwise, they will still require some processing, +even though they are not visible. \section2 Rendering Text -The text rendering with the Software adaptation is based on software -rasterization and does not respond as well to transformations such as scaling -as when using OpenGL. The quality is similar to choosing \l [QML] {Text::renderType} -{Text.NativeRendering} with \l [QML] {Text} items. -\section2 Qt Multimedia VideoOutput -The VideoOutput item of the Qt Multimedia module is not supported with the software -adaptation. This is because VideoOutput uses the QVideoRendererControl item which -requires custom QSGGeometryNode behavior that is only present in the default OpenGL -adaptation. +The text rendering with the Software adaptation is based on software rasterization and does not +respond as well to transformations such as scaling, compared to when using OpenGL. The quality is +similar to choosing \l [QML] {Text::renderType}{Text.NativeRendering} with \l [QML] {Text} items. +\section2 Qt Multimedia VideoOutput +The Qt Multimedia module's VideoOutput item is not supported with the Software adaptation. This +is because VideoOutput uses the QVideoRendererControl item which requires custom QSGGeometryNode +behavior, which is only present in the default OpenGL adaptation. */ @@ -152,251 +145,228 @@ adaptation. \title Qt Quick Direct3D 12 Adaptation \page qtquick-visualcanvas-adaptations-d3d12.html -The Direct3D 12 adaptation for Windows 10 (both Win32 (\c windows platform -plugin) and UWP (\c winrt platform plugin)) is shipped as a dynamically loaded -plugin. It will not be functional on earlier Windows versions. The building of -the plugin is enabled automatically whenever the necessary D3D and DXGI -develpoment files are present. In practice this currently means Visual Studio -2015 and newer. +The Direct3D 12 adaptation for Windows 10, both in Win32 (\c windows platform plugin) and in UWP +(\c winrt platform plugin), is shipped as a dynamically loaded plugin. This adaptation doesn't work +on earlier Windows versions. Building this plugin is enabled automatically, whenever the necessary +D3D and DXGI develpoment files are present. In practice, this currently means Visual Studio 2015 +and newer. -The adaptation is available both in normal, OpenGL-enabled Qt builds and also -when Qt was configured with \c{-no-opengl}. However, it is never the default, -meaning the user or the application has to explicitly request it by setting the -\c{QT_QUICK_BACKEND} environment variable to \c{d3d12} or by calling -QQuickWindow::setSceneGraphBackend(). +The adaptation is available both in normal, OpenGL-enabled Qt builds, and also when Qt is +configured with \c{-no-opengl}. However, it's never the default, meaning that the user or the +application has to explicitly request it by setting the \c{QT_QUICK_BACKEND} environment variable +to \c{d3d12} or by calling QQuickWindow::setSceneGraphBackend(). \section2 Motivation -This experimental adaptation is the first Qt Quick backend focusing on a -modern, lower-level graphics API in combination with a windowing system -interface different from the traditional approaches used in combination with -OpenGL. - -It also allows better integration with Windows, Direct3D being the primary -vendor-supported solution. This means that there are fewer problems anticipated -with drivers, operations like window resizes, and special events like graphics -device loss caused by device resets or graphics driver updates. - -Performance-wise the general expectation is a somewhat lower CPU usage compared -to OpenGL due to lower driver overhead, and a higher GPU utilization with less -wasted idle time. The backend does not heavily utilize threads yet, which means -there are opportunities for further improvements in the future, for example to -further optimize image loading. - -The D3D12 backend also introduces support for pre-compiled shaders. All the -backend's own shaders (used by the built-in materials on which the Rectangle, -Image, Text, etc. QML types are built) are compiled to D3D shader bytecode when -compiling Qt. Applications using ShaderEffect items can chose to ship bytecode -either in regular files or via the Qt resource system, or use HLSL source -strings. Unlike OpenGL, the compilation for the latter is properly threaded, -meaning shader compilation will not block the application and its user +This experimental adaptation is the first Qt Quick backend that focuses on a modern, lower-level +graphics API in combination with a windowing system interface that's different from the traditional +approaches used in combination with OpenGL. + +This adaptation also allows better integration with Windows, as Direct3D is the primary +vendor-supported solution. Consequently, there are fewer problems anticipated with drivers, +operations like window resizes, and special events like graphics device loss caused by device +resets or graphics driver updates. + +Performance-wise, the general expectation is a somewhat lower CPU usage compared to OpenGL, due to +lower driver overhead, and a higher GPU utilization with less idle time wastage. The backend +doesn't heavily utilize threads yet, which means there are opportunities for further improvements +in the future, for example to further optimize image loading. + +The D3D12 backend also introduces support for pre-compiled shaders. All the backend's own shaders +(used by the built-in materials on which the Rectangle, Image, Text, and other QML types are built +with) are compiled to D3D shader bytecode when you compile Qt. Applications using ShaderEffect +items can choose to ship bytecode either in regular files, via the Qt resource system, or use +High Level Shading Language for DirectX (HLSL) source strings. Unlike OpenGL, the compilation for +HLSL is properly threaded, meaning shader compilation won't block the application and its user interface. \section2 Graphics Adapters -The plugin does not necessarily require hardware acceleration. Using WARP, the -Direct3D software rasterizer, is also an option. By default the first adapter -providing hardware acceleration is chosen. To override this, in order to use -another graphics adapter or to force the usage of the software rasterizer, set -the environment variable \c{QT_D3D_ADAPTER_INDEX} to the index of the adapter. -The discovered adapters are printed at startup when \c{QSG_INFO} or the logging -category \c{qt.scenegraph.general} is enabled. +The plugin does not necessarily require hardware acceleration. You can also use WARP, the Direct3D +software rasterizer. By default, the first adapter providing hardware acceleration is chosen. To +override this and use another graphics adapter or to force the use of the software rasterizer, set +the \c{QT_D3D_ADAPTER_INDEX} environment variable to the index of the adapter. The adapters +discovered are printed at startup when \c{QSG_INFO} or the \c{qt.scenegraph.general} logging +category is enabled. \section2 Troubleshooting -When encountering issues, always set the \c{QSG_INFO} and \c{QT_D3D_DEBUG} -environment variables to 1 in order to get debug and warning messages printed -on the debug output. The latter enables the Direct3D debug layer. Note that the -debug layer should not be enabled in production use since it can significantly -impact performance (CPU load) due to increased API overhead. +If you encounter issues, always set the \c{QSG_INFO} and \c{QT_D3D_DEBUG} environment variables +to \c 1, to get debug and warning messages printed on the debug output. \c{QT_D3D_DEBUG} enables +the Direct3D debug layer. + +\note The debug layer shouldn't be enabled in production use, since it can significantly impact +performance (CPU load) due to increased API overhead. \section2 Render Loops -By default the D3D12 adaptation uses a single-threaded render loop similar to -OpenGL's \c windows render loop. There is also a threaded variant available, that -can be requested by setting the \c{QSG_RENDER_LOOP} environment variable to \c -threaded. However, due to conceptual limitations in DXGI, the windowing system -interface, the threaded loop is prone to deadlocks when multiple QQuickWindow -or QQuickView instances are shown. Therefore the default is the single-threaded -loop for the time being. This means that with the D3D12 backend applications -are expected to move their work from the main (GUI) thread out to worker -threads, instead of expecting Qt to keep the GUI thread responsive and suitable -for heavy, blocking operations. - -See the \l{qtquick-visualcanvas-scenegraph.html}{Scene Graph page} for more -information on render loops and -\l{https://msdn.microsoft.com/en-us/library/windows/desktop/ee417025(v=vs.85).aspx#multithreading_and_dxgi}{the -MSDN page for DXGI} regarding the issues with multithreading. +By default, the D3D12 adaptation uses a single-threaded render loop similar to OpenGL's \c windows +render loop. A threaded variant is also available, that you can request by setting the +\c{QSG_RENDER_LOOP} environment variable to \c threaded. However, due to conceptual limitations in +DXGI, the windowing system interface, the threaded loop is prone to deadlocks when multiple +QQuickWindow or QQuickView instances are shown. Consequently, for the time being, the default is +the single-threaded loop. This means that with the D3D12 backend, applications are expected to move +their work from the main (GUI) thread out to worker threads, instead of expecting Qt to keep the +GUI thread responsive and suitable for heavy, blocking operations. + +For more information see \l{qtquick-visualcanvas-scenegraph.html}{Qt Quick Scene Graph} for +details on render loops and +\l{https://docs.microsoft.com/en-us/windows/desktop/direct3darticles/dxgi-best-practices#multithreading-and-dxgi}{Multithreading and DXGI} +regarding the issues with multithreading. \section2 Renderer -The scenegraph renderer in the D3D12 adaptation does not currently perform any -batching. This is less of an issue, unlike OpenGL, because state changes are -not presenting any problems in the first place. The simpler renderer logic can -also lead to lower CPU overhead in some cases. The trade-offs between the -various approaches are currently under research. +The scene graph renderer in the D3D12 adaptation currently doesn't perform any batching. This is +less of an issue, unlike OpenGL, because state changes don't present any problems in the first +place. The simpler renderer logic can also lead to lower CPU overhead in some cases. The trade-offs +between the various approaches are currently under research. \section2 Shader Effects -The ShaderEffect QML type is fully functional with the D3D12 adaptation as well. -However, the interpretation of the fragmentShader and vertexShader properties is -different than with OpenGL. +The ShaderEffect QML type is fully functional with the D3D12 adaptation as well. However, the +interpretation of the fragmentShader and vertexShader properties is different than with OpenGL. -With D3D12, these strings can either be an URL for a local file or a file in -the resource system, or a HLSL source string. The former indicates that the -file in question contains pre-compiled D3D shader bytecode generated by the -\c fxc tool, or, alternatively, HLSL source code. The type of the file is detected -automatically. This means that the D3D12 backend supports all options from -GraphicsInfo.shaderCompilationType and GraphicsInfo.shaderSourceType. +With D3D12, these strings can either be a URL for a local file, a file in the resource system, +or an HLSL source string. Using a URL for a local file or a file in the resource system +indicates that the file in question contains pre-compiled D3D shader bytecode generated by the +\c fxc tool, or, alternatively, HLSL source code. The type of file is detected automatically. +This means that the D3D12 backend supports all options from GraphicsInfo.shaderCompilationType +and GraphicsInfo.shaderSourceType. -Unlike OpenGL, there is a QFileSelector with the extra selector \c hlsl used -whenever opening a file. This allows easy creation of ShaderEffect items that -are functional across both backends, for example by placing the GLSL source -code into \c{shaders/effect.frag}, the HLSL source code or - preferably - -pre-compiled bytecode into \c{shaders/+hlsl/effect.frag}, while simply writing -\c{fragmentShader: "qrc:shaders/effect.frag"} in QML. - -See the ShaderEffect documentation for more details. +Unlike OpenGL, whenever you open a file, there is a QFileSelector with the extra \c hlsl selector +used. This provides easy creation of ShaderEffect items that are functional across both backends, +for example by placing the GLSL source code into \c{shaders/effect.frag}, the HLSL source code or +- preferably - pre-compiled bytecode into \c{shaders/+hlsl/effect.frag}, while simply writing +\c{fragmentShader: "qrc:shaders/effect.frag"} in QML. For more details, see ShaderEffect. \section2 Multisample Render Targets -The Direct3D 12 adaptation ignores the QSurfaceFormat set on the QQuickWindow -or QQuickView (or set via QSurfaceFormat::setDefaultFormat()), with two -exceptions: QSurfaceFormat::samples() and QSurfaceFormat::alphaBufferSize() are -still taken into account. When the samples value is greater than 1, multisample -offscreen render targets will be created with the specified sample count and a -quality of the maximum supported quality level. The backend automatically -performs resolving into the non-multisample swapchain buffers after each frame. +The Direct3D 12 adaptation ignores the QSurfaceFormat set on the QQuickWindow or QQuickView, or +set via QSurfaceFormat::setDefaultFormat(), with two exceptions: QSurfaceFormat::samples() and +QSurfaceFormat::alphaBufferSize() are still taken into account. When the sample value is greater +than 1, multisample offscreen render targets will be created with the specified sample count at +the maximum supported quality level. The backend automatically performs resolving into the +non-multisample swapchain buffers after each frame. \section2 Semi-transparent Windows -When the alpha channel is enabled either via -QQuickWindow::setDefaultAlphaBuffer() or by setting alphaBufferSize to a -non-zero value in the window's QSurfaceFormat or in the global format managed -by QSurfaceFormat::setDefaultFormat(), the D3D12 backend will create a -swapchain for composition and go through DirectComposition since the flip model -swapchain (which is mandatory) would not support transparency otherwise. +When the alpha channel is enabled either via QQuickWindow::setDefaultAlphaBuffer() or by setting +alphaBufferSize to a non-zero value in the window's QSurfaceFormat or in the global format managed +by QSurfaceFormat::setDefaultFormat(), the D3D12 backend will create a swapchain for composition +and go through DirectComposition. This is necessary, because the mandatory flip model swapchain +wouldn't support transparency otherwise. -It is therefore important not to unneccessarily request an alpha channel. When -the alphaBufferSize is 0 or the default -1, all these extra steps can be -avoided and the traditional window-based swapchain is sufficient. +Therefore, it's important not to unneccessarily request an alpha channel. When the alphaBufferSize +is 0 or the default -1, all these extra steps can be avoided and the traditional window-based +swapchain is sufficient. -This is not relevant on WinRT because there the backend always uses a -composition swapchain which is associated with the ISwapChainPanel that backs -QWindow on that platform. +On WinRT, this isn't relevant because the backend there always uses a composition swapchain which +is associated with the ISwapChainPanel that backs QWindow on that platform. \section2 Mipmaps -Mipmap generation is supported and handled transparently to the applications -via a built-in compute shader, but is experimental and only supports -power-of-two images at the moment. Textures of other size will work too, but -this involves a QImage-based scaling on the CPU first. Therefore avoid enabling -mipmapping for NPOT images whenever possible. +Mipmap generation is supported and handled transparently to the applications via a built-in compute +shader. However, at the moment, this feature is experimental and only supports power-of-two images. +Textures of other size will work too, but this involves a QImage-based scaling on the CPU first. +Therefore, avoid enabling mipmapping for Non-Power-Of-Two (NPOT) images whenever possible. \section2 Image Formats -When creating textures via the C++ scenegraph APIs like -QQuickWindow::createTextureFromImage(), 32-bit formats will not involve any -conversion, they will map directly to the corresponding \c{R8G8B8A8_UNORM} or -\c{B8G8R8A8_UNORM} format. Everything else will trigger a QImage-based format -conversion on the CPU first. +When creating textures via C++ scene graph APIs like QQuickWindow::createTextureFromImage(), 32-bit +formats won't involve any conversion, they'll map directly to the corresponding \c{R8G8B8A8_UNORM} +or \c{B8G8R8A8_UNORM} format. Everything else will trigger a QImage-based format conversion on the +CPU first. \section2 Unsupported Features -Particles and some other OpenGL-dependent utilities, like -QQuickFramebufferObject, are not currently supported. +Particles and some other OpenGL-dependent utilities, like QQuickFramebufferObject, are currently +not supported. -Like with the \l{qtquick-visualcanvas-adaptations-software.html}{Software -adaptation}, text is always rendered using the native method. Distance -field-based text rendering is not currently implemented. +Like with \l{qtquick-visualcanvas-adaptations-software.html}{Software adaptation}, text is always +rendered using the native method. Distance field-based text rendering is currently not implemented. -The shader sources in the \l {Qt Graphical Effects} module have not been ported -to any format other than the OpenGL 2.0 compatible one, meaning the QML types -provided by that module are not currently functional with the D3D12 backend. +The shader sources in the \l {Qt Graphical Effects} module have not been ported to any format other +than the OpenGL 2.0 compatible one, meaning that the QML types provided by that module are currently +not functional with the D3D12 backend. -Texture atlases are not currently in use. +Texture atlases are currently not in use. -The renderer may lack support for certain minor features, for example drawing -points and lines with a width other than 1. +The renderer may lack support for certain minor features, such as drawing points and lines with a +width other than 1. -Custom Qt Quick items using custom scenegraph nodes can be problematic. -Materials are inherently tied to the graphics API. Therefore only items using -the utility rectangle and image nodes are functional across all adaptations. +Custom Qt Quick items using custom scene graph nodes can be problematic because materials are +inherently tied to the graphics API. Therefore, only items that use the utility rectangle and image +nodes are functional across all adaptations. -QQuickWidget and its underlying OpenGL-based compositing architecture is not -supported. If mixing with QWidget-based user interfaces is desired, use -QWidget::createWindowContainer() to embed the native window of the QQuickWindow -or QQuickView. +QQuickWidget and its underlying OpenGL-based compositing architecture is not supported. If you need +to mix with QWidget-based user interfaces, use QWidget::createWindowContainer() to embed the native +window of the QQuickWindow or QQuickView. -Finally, rendering via QSGEngine and QSGAbstractRenderer is not feasible with -the D3D12 adaptation at the moment. +Finally, rendering via QSGEngine and QSGAbstractRenderer is not feasible with the D3D12 adaptation +at the moment. \section2 Related APIs -To integrate custom Direct3D 12 rendering, use QSGRenderNode in combination -with QSGRendererInterface. This approach does not rely on OpenGL contexts or -API specifics like framebuffers, and allows exposing the graphics device and -command buffer from the adaptation. It is not necessarily suitable for easy -integration of all types of content, in particular true 3D, so it will likely -get complemented by an alternative to QQuickFramebufferObject in future -releases. +To integrate custom Direct3D 12 rendering, use QSGRenderNode in combination with +QSGRendererInterface. This approach doesn't rely on OpenGL contexts or API specifics like +framebuffers, and allows exposing the graphics device and command buffer from the adaptation. It's +not necessarily suitable for easy integration of all types of content, in particular true 3D, so +it'll likely get complemented by an alternative to QQuickFramebufferObject in future releases. -To perform runtime decisions based on the adaptation in use, use -QSGRendererInterface from C++ and GraphicsInfo from QML. They can also be used -to check the level of shader support (shading language, compilation approach). +To perform runtime decisions based on the adaptation, use QSGRendererInterface from C++ and +GraphicsInfo from QML. They can also be used to check the level of shader support: shading +language, compilation approach, and so on. -When creating custom items, use the new QSGRectangleNode and QSGImageNode -classes. These replace the now deprecated QSGSimpleRectNode and -QSGSimpleTextureNode. Unlike their predecessors, the new classes are -interfaces, and implementations are created via the factory functions -QQuickWindow::createRectangleNode() and QQuickWindow::createImageNode(). +When creating custom items, use the new QSGRectangleNode and QSGImageNode classes. These replace +the now deprecated QSGSimpleRectNode and QSGSimpleTextureNode. Unlike their predecessors, these new +classes are interfaces, and implementations are created via the QQuickWindow::createRectangleNode() +and QQuickWindow::createImageNode() factory functions. \section2 Advanced Configuration -The D3D12 adaptation can keep multiple frames in flight, similarly to modern -game engines. This is somewhat different from the traditional render - swap - -wait for vsync model and allows better GPU utilization at the expense of higher -resource usage. This means that the renderer will be a number of frames ahead -of what is displayed on the screen. +The D3D12 adaptation can keep multiple frames in flight, similar to modern game engines. This is +somewhat different from the traditional "render - swap - wait for vsync" model and allows for +better GPU utilization at the expense of higher resource use. This means that the renderer will +be a number of frames ahead of what is displayed on the screen. -For a discussion of flip model swap chains and the typical configuration -parameters, refer to -\l{https://software.intel.com/en-us/articles/sample-application-for-direct3d-12-flip-model-swap-chains}{this -article}. +For a discussion of flip model swap chains and the typical configuration parameters, refer to +\l{https://software.intel.com/en-us/articles/sample-application-for-direct3d-12-flip-model-swap-chains} +{Sample Application for Direct3D 12 Flip Model Swap Chains}. -Vertical synchronization is always enabled, meaning Present() is invoked with -an interval of 1. +Vertical synchronization is always enabled, meaning Present() is invoked with an interval of 1. The configuration can be changed by setting the following environment variables: -\list - -\li \c{QT_D3D_BUFFER_COUNT} - The number of swap chain buffers in range 2 - 4. -The default value is 3. - -\li \c{QT_D3D_FRAME_COUNT} - The number of frames prepared without blocking in -range 1 - 4. Note that Present will start blocking after queuing 3 frames -(regardless of \c{QT_D3D_BUFFER_COUNT}), unless the waitable object is in use. -Note that every additional frame increases GPU resource usage since geometry -and constant buffer data will have to be duplicated, and involves more -bookkeeping on the CPU side. The default value is 2. - -\li \c{QT_D3D_WAITABLE_SWAP_CHAIN_MAX_LATENCY} - When set to a value between 1 -and 16, the frame latency is set to the specified value. This changes the limit -for Present() and will trigger a wait for an available swap chain buffer when -beginning each frame. Refer to the article above for a detailed discussion. -This is considered experimental for now and the default value is 0 (disabled). - -\li \c{QT_D3D_BLOCKING_PRESENT} - When set to a non-zero value, there will be -CPU-side wait for the GPU to finish its work after each call to Present. This -effectively kills all parallelism but makes the behavior resemble the -traditional swap-blocks-for-vsync model, and can therefore be useful in some -special cases. This is not the same as setting the frame count to 1 because -that still avoids blocking after Present, and may block only when starting to -prepare the next frame (or may not block at all depending on the time gap -between the frames). By default blocking present is disabled. - -\endlist +\table + \header + \li Environment variable + \li Description + \row + \li \c{QT_D3D_BUFFER_COUNT} + \li The number of swap chain buffers in range 2 - 4. The default value is 3. + \row + \li \c{QT_D3D_FRAME_COUNT} + \li The number of frames prepared without blocking in range 1 - 4. The default value is 2. + Present() starts blocking after queuing 3 frames (regardless of + \c{QT_D3D_BUFFER_COUNT}), unless the waitable object is in use. Every additional frame + increases GPU resource usage since geometry and constant buffer data needs to be + duplicated, and involves more bookkeeping on the CPU side. + \row + \li \c{QT_D3D_WAITABLE_SWAP_CHAIN_MAX_LATENCY} + \li The frame latency in range 1 - 16. The default value is 0 (disabled). + Changes the limit for Present() and triggers a wait for an available swap chain buffer + when beginning each frame. For a detailed discussion, see the article linked above. + \note Currently, this behavior is experimental. + \row + \li \c{QT_D3D_BLOCKING_PRESENT} + \li The time the CPU should wait, a non-zero value, for the GPU to finish its work after + each call to Present(). The default value is 0 (disabled). This behavior effectively + kills all parallelism but makes the behavior resemble the traditional + swap-blocks-for-vsync model, which can be useful in some special cases. However, this + behavior is not the same as setting the frame count to 1 because that still avoids + blocking after Present(), and may only block when starting to prepare the next frame + (or may not block at all depending on the time gap between the frames). +\endtable */ @@ -404,68 +374,72 @@ between the frames). By default blocking present is disabled. \title Qt Quick OpenVG Adaptation \page qtquick-visualcanvas-adaptations-openvg.html -The OpenVG adaptation is an alternative renderer for \l {Qt Quick} 2 that will -renderer the contents of the scene graph using OpenVG commands to provide -hardware-acclerated 2D vector and raster graphics. Much like the Software -adaptation, some features and optimizations are no longer available. Most -Qt Quick 2 applications will run without modification though any attempts to -use unsupported features will be ignored. +The OpenVG adaptation is an alternative renderer for \l{Qt Quick} 2 that renders the contents of +the scene graph using OpenVG commands to provide hardware accelerated 2D vector and raster +graphics. Much like the \l{qtquick-visualcanvas-adaptations-software.html}{Software Adaptation}, +some features and optimizations are no longer available. Most Qt Quick 2 applications will run +without modification though any attempts to use unsupported features will be ignored. \section2 EGL Requirement -Unlike the defualt OpenGL Renderer, there is no built in support for acquiring -an OpenVG context. This means that the renderer has the responsbility of -requesting and managing the the current context. To do this EGL has to be used -directly in the OpenVG renderer. This means that the OpenVG renderer is only -usable with platform plugins that support creating QWindows with support for -QSurfaceFormat::OpenVG. From this window, the renderer can get an EGLSurface -which can be used with an EGLContext to render OpenVG content. + +Unlike the default OpenGL Renderer, there is no built-in support to acquire an OpenVG context. +This means that the renderer is responsible for requesting and managing the the current context. +To do this, you use EGL directly in the OpenVG renderer. Consequently, the OpenVG renderer can only +be used with platform plugins that support creating QWindows with support for +QSurfaceFormat::OpenVG. From this window, the renderer can get an EGLSurface which can then be used +with an EGLContext to render OpenVG content. \section2 Renderer -The OpenVG Renderer works by using the OpenVG API to send commands and data to -a Vector GPU which will render the scenegraph in an accelerated manner, offloading -graphics rendering from the CPU. Many operations like the rendering of rectangles -and fonts glyphs ideal for OpenVG because these can be represented as paths which -are stroked and filled. Rendering scenegraph items that would typically involve -textures are handled in the OpenVG renderer by using VGImage. In addition when -rendering to offscreen surfaces (like when using Layers), the scene subtree is -rendered to a VGImage which can be reused in the scene. + +The OpenVG Renderer uses the OpenVG API to send commands and data to a Vector GPU that renders the +scene graph in an accelerated manner, offloading graphics rendering from the CPU. Many operations +like the rendering of rectangles and font glyphs are ideal for OpenVG because they can be +represented as paths which are stroked and filled. Rendering scene graph items that would typically +involve textures are handled in the OpenVG renderer using VGImage. Additionally, when you render +to offscreen surfaces (like with Layers), the scene subtree is rendered to a VGImage which can be +reused in the scene. \section2 Render Loop -The OpenVG Renderer mirrors the behavior of the Basic render loop and will execute -all OpenVG commands in a single thread. -See the \l{qtquick-visualcanvas-scenegraph.html}{Scene Graph page} for more -information on render loops +The OpenVG Renderer mirrors the behavior of the Basic render loop and it runs all OpenVG commands +in a single thread. + +For more information on render loops, see +\l{qtquick-visualcanvas-scenegraph.html}{Qt Quick Scene Graph}. \section2 Shader Effects -ShaderEffect components in QtQuick 2 can not be rendered by the OpenVG adaptation. -While it is possible to user ShaderEffectSource and QML Item Layers (which are both -offscreen surfaces), it is not actually possible to apply shader effects to them -via the ShaderEffect item. This is because OpenVG lacks an API for applying per -vertex and per fragment shader operations. It may be possible however to take -advantage of Image Filter operations in the OpenVG API to get similar effects to -what is provided by ShaderEffects in custom items. To integrate custom OpenVG -rendering, use QSGRenderNode in combination with QSGRendererInterface. + +ShaderEffect components in QtQuick 2 can't be rendered by the OpenVG adaptation. While it's +possible to use ShaderEffectSource and QML Item Layers (which are both offscreen surfaces), it's +not possible to apply shader effects to them via the ShaderEffect item. This is because OpenVG +lacks an API for applying per vertex and per fragment shader operations. However, you may be able +to take advantage of Image Filter operations in the OpenVG API to get effects that are similar to +what ShaderEffects provides in custom items. To integrate custom OpenVG rendering, use +QSGRenderNode in combination with QSGRendererInterface. \section2 Qt Graphical Effects Module -\l {Qt Graphical Effects} uses ShaderEffect items to render effects. If you use -graphical effects from this module, then you should not hide the source -item so that the original item can still be rendered. + +\l {Qt Graphical Effects} uses ShaderEffect items to render effects. If you use graphical effects +from this module, then you shouldn't hide the source item so that the original item can still be +rendered. \section2 Particle Effects -It is not possible to render particle effects with the OpenVG adaptation. Whenever -possible, remove particles completely from the scene. Otherwise they will still -require some processing, even though they are not visible. + +It's not possible to render particle effects with the OpenVG adaptation. Whenever possible, remove +particles completely from the scene. Otherwise they'll still require some processing, even though +they are not visible. \section2 Rendering Text -The text rendering with the OpenVG adaptation is based on rendering the glpyh -paths, and does not use the distance fields technique used by the OpenGL backend. + +Text rendering with the OpenVG adaptation is based on rendering the glyph paths, and doesn't use +the distance fields technique, unlike with the OpenGL backend. \section2 Perspective Transforms -The OpenVG API does not allow paths to be transformed with non-affine transforms, -while it is possible with Qt Quick. This means that rendering components using -paths like Rectangles and Text, when applying perspective transforms the OpenVG -backend will first render to a VGImage before applying transformations. This uses -more memory at runtime and is a slower path so avoid doing this if necessary. + +The OpenVG API doesn't allow paths to be transformed with non-affine transforms, but it's +possible with Qt Quick. Consquently, when you render components using paths like Rectangles and +Text while applying perspective transforms, the OpenVG backend first renders to a VGImage before +applying transformations. This behavior uses more memory at runtime and takes more time; avoid it +if possible. */ -- cgit v1.2.3 From 3e716029ae61bf4c7bb33643ac331156e70e34f1 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 21 May 2019 15:10:45 +0200 Subject: Don't add local for anonymous function's "name" Instead, populate their "name" property directly from the surrounding object pattern if applicable, without adding locals. This fixes some ecmascript tests where functions were assigned to the key "eval" in an object. The JS engine then rejected that because you shouldn't use eval in strict mode. That should be close enough to test for regressions. Fixes: QTBUG-75880 Change-Id: Iacc45a3f7b0eb90cddc6ecf6d2bada616d2cf355 Reviewed-by: Lars Knoll --- src/qml/compiler/qv4codegen.cpp | 5 +++-- src/qml/compiler/qv4codegen_p.h | 19 +++++++++++++++---- src/qml/parser/qqmljs.g | 4 ---- 3 files changed, 18 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 3fdba08f20..d2d913408a 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -1061,6 +1061,7 @@ bool Codegen::visit(Expression *ast) TailCallBlocker blockTailCalls(this); statement(ast->left); blockTailCalls.unblock(); + clearExprResultName(); // The name only holds for the left part accept(ast->right); return false; } @@ -2523,7 +2524,7 @@ bool Codegen::visit(ObjectPattern *ast) { RegisterScope innerScope(this); - Reference value = expression(p->initializer); + Reference value = expression(p->initializer, name); if (hasError) return false; value.loadInAccumulator(); @@ -2965,7 +2966,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, // already defined return leaveContext(); - _context->name = name; + _context->name = name.isEmpty() ? currentExpr().result().name : name; _module->functions.append(_context); _context->functionIndex = _module->functions.count() - 1; diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h index ad86483132..958dd16816 100644 --- a/src/qml/compiler/qv4codegen_p.h +++ b/src/qml/compiler/qv4codegen_p.h @@ -196,8 +196,9 @@ public: codegen = cg; } - Reference() : + Reference(const QString &name = QString()) : constant(0), + name(name), isArgOrEval(false), isReadonly(false), isReferenceToConst(false), @@ -414,6 +415,11 @@ protected: bool _trueBlockFollowsCondition = false; public: + explicit Result(const QString &name) + : _result(name) + , _requested(ex) + {} + explicit Result(const Reference &lrvalue) : _result(lrvalue) , _requested(ex) @@ -472,6 +478,10 @@ protected: void setResult(Reference &&result) { _result = std::move(result); } + + void clearResultName() { + _result.name.clear(); + } }; void enterContext(AST::Node *node); @@ -519,12 +529,12 @@ protected: const BytecodeGenerator::Label *iffalse, bool trueBlockFollowsCondition); - inline Reference expression(AST::ExpressionNode *ast) + inline Reference expression(AST::ExpressionNode *ast, const QString &name = QString()) { if (!ast || hasError) return Reference(); - pushExpr(); + pushExpr(name); ast->accept(this); return popResult(); } @@ -712,6 +722,7 @@ protected: inline void setExprResult(const Reference &result) { m_expressions.back().setResult(result); } inline void setExprResult(Reference &&result) { m_expressions.back().setResult(std::move(result)); } inline Reference exprResult() const { return m_expressions.back().result(); } + inline void clearExprResultName() { m_expressions.back().clearResultName(); } inline bool exprAccept(Format f) { return m_expressions.back().accept(f); } @@ -719,7 +730,7 @@ protected: inline void pushExpr(Result &&expr) { m_expressions.push_back(std::move(expr)); } inline void pushExpr(const Result &expr) { m_expressions.push_back(expr); } - inline void pushExpr() { m_expressions.emplace_back(); } + inline void pushExpr(const QString &name = QString()) { m_expressions.emplace_back(name); } inline Result popExpr() { diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index 8ae51a795f..27f23a6fa7 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -1773,10 +1773,6 @@ PropertyDefinition: PropertyName T_COLON AssignmentExpression_In; /. case $rule_number: { AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(1).PropertyName, sym(3).Expression); - if (auto *f = asAnonymousFunctionDefinition(sym(3).Expression)) { - if (!AST::cast(sym(1).PropertyName)) - f->name = driver->newStringRef(sym(1).PropertyName->asString()); - } if (auto *c = asAnonymousClassDefinition(sym(3).Expression)) { if (!AST::cast(sym(1).PropertyName)) c->name = driver->newStringRef(sym(1).PropertyName->asString()); -- cgit v1.2.3 From aefbf418b6d99f87f7bcc7df1eb530c278a17ab4 Mon Sep 17 00:00:00 2001 From: Vova Mshanetskiy Date: Fri, 24 May 2019 14:46:42 +0300 Subject: QQuickTextControl: Fix Qt::ImAbsolutePosition query Qt::ImAbsolutePosition is documented to return cursor position, not anchor position. That's also what QQuickTextInput and QWidgetTextControl return. Change-Id: I91f9343f5f33c9d43875dbad515bfda77c13058d Reviewed-by: Richard Moe Gustavsen --- src/quick/items/qquicktextcontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp index 1dd593cc1a..56c735ea38 100644 --- a/src/quick/items/qquicktextcontrol.cpp +++ b/src/quick/items/qquicktextcontrol.cpp @@ -1403,7 +1403,7 @@ QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVar case Qt::ImAnchorPosition: return QVariant(d->cursor.anchor() - block.position()); case Qt::ImAbsolutePosition: - return QVariant(d->cursor.anchor()); + return QVariant(d->cursor.position()); case Qt::ImTextAfterCursor: { int maxLength = argument.isValid() ? argument.toInt() : 1024; -- cgit v1.2.3 From 5af16fb4dfa39ead82240f5ffbc004634f3c288f Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 27 May 2019 16:32:00 +0200 Subject: Fix mistakes in 9b36512b9453f429644b0c388d381f7a2fc0f825 Undo change to signature of textureProviderDestroyed, and reinstate test for disconnected item having a window, and instead ensure we are destroyed earlier while the item is still valid. Fixes: QTBUG-76055 Change-Id: I0c6c13cd44d3364984e0245b3b048f4aa183b43a Reviewed-by: Daniel Smith Reviewed-by: Simon Hausmann --- src/quick/items/qquickopenglshadereffect.cpp | 7 ++++--- src/quick/items/qquickopenglshadereffect_p.h | 2 +- src/quick/items/qquickopenglshadereffectnode.cpp | 2 +- src/quick/items/qquickopenglshadereffectnode_p.h | 2 +- src/quick/items/qquickshadereffect.cpp | 14 ++++++++++++++ src/quick/items/qquickshadereffect_p.h | 1 + 6 files changed, 22 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp index 76cb3ace5c..3aa00340b2 100644 --- a/src/quick/items/qquickopenglshadereffect.cpp +++ b/src/quick/items/qquickopenglshadereffect.cpp @@ -221,7 +221,7 @@ QQuickOpenGLShaderEffectCommon::~QQuickOpenGLShaderEffectCommon() clearSignalMappers(shaderType); } -void QQuickOpenGLShaderEffectCommon::disconnectPropertySignals(QObject *obj, Key::ShaderType shaderType) +void QQuickOpenGLShaderEffectCommon::disconnectPropertySignals(QQuickItem *item, Key::ShaderType shaderType) { for (int i = 0; i < uniformData[shaderType].size(); ++i) { if (signalMappers[shaderType].at(i) == 0) @@ -229,11 +229,12 @@ void QQuickOpenGLShaderEffectCommon::disconnectPropertySignals(QObject *obj, Key const UniformData &d = uniformData[shaderType].at(i); auto mapper = signalMappers[shaderType].at(i); void *a = mapper; - QObjectPrivate::disconnect(obj, mapper->signalIndex(), &a); + QObjectPrivate::disconnect(item, mapper->signalIndex(), &a); if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) { QQuickItem *source = qobject_cast(qvariant_cast(d.value)); if (source) { - QQuickItemPrivate::get(source)->derefWindow(); + if (item->window()) + QQuickItemPrivate::get(source)->derefWindow(); QObject::disconnect(source, SIGNAL(destroyed(QObject*)), host, SLOT(sourceDestroyed(QObject*))); } } diff --git a/src/quick/items/qquickopenglshadereffect_p.h b/src/quick/items/qquickopenglshadereffect_p.h index 3087c1eb0b..0c2adadc62 100644 --- a/src/quick/items/qquickopenglshadereffect_p.h +++ b/src/quick/items/qquickopenglshadereffect_p.h @@ -89,7 +89,7 @@ struct Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffectCommon ~QQuickOpenGLShaderEffectCommon(); - void disconnectPropertySignals(QObject *item, Key::ShaderType shaderType); + void disconnectPropertySignals(QQuickItem *item, Key::ShaderType shaderType); void connectPropertySignals(QQuickItem *item, const QMetaObject *itemMetaObject, Key::ShaderType shaderType); void updateParseLog(bool ignoreAttributes); void lookThroughShaderCode(QQuickItem *item, const QMetaObject *itemMetaObject, Key::ShaderType shaderType, const QByteArray &code); diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp index f96ebebcd6..3ccd2a76f7 100644 --- a/src/quick/items/qquickopenglshadereffectnode.cpp +++ b/src/quick/items/qquickopenglshadereffectnode.cpp @@ -505,7 +505,7 @@ void QQuickOpenGLShaderEffectNode::markDirtyTexture() Q_EMIT dirtyTexture(); } -void QQuickOpenGLShaderEffectNode::textureProviderDestroyed(const QObject *object) +void QQuickOpenGLShaderEffectNode::textureProviderDestroyed(QObject *object) { Q_ASSERT(material()); static_cast(material())->invalidateTextureProvider(object); diff --git a/src/quick/items/qquickopenglshadereffectnode_p.h b/src/quick/items/qquickopenglshadereffectnode_p.h index 6d68ba87b9..705b8d4f47 100644 --- a/src/quick/items/qquickopenglshadereffectnode_p.h +++ b/src/quick/items/qquickopenglshadereffectnode_p.h @@ -159,7 +159,7 @@ Q_SIGNALS: private Q_SLOTS: void markDirtyTexture(); - void textureProviderDestroyed(const QObject *object); + void textureProviderDestroyed(QObject *object); }; QT_END_NAMESPACE diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index 05d9e5e36d..3721731f68 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -515,6 +515,20 @@ QQuickShaderEffect::QQuickShaderEffect(QQuickItem *parent) m_impl = new QQuickGenericShaderEffect(this, this); } +QQuickShaderEffect::~QQuickShaderEffect() +{ + // Delete the implementations now, while they still have have + // valid references back to us. +#if QT_CONFIG(opengl) + auto *glImpl = m_glImpl; + m_glImpl = nullptr; + delete glImpl; +#endif + auto *impl = m_impl; + m_impl = nullptr; + delete impl; +} + /*! \qmlproperty string QtQuick::ShaderEffect::fragmentShader diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h index cabad930fc..c5bddc40d2 100644 --- a/src/quick/items/qquickshadereffect_p.h +++ b/src/quick/items/qquickshadereffect_p.h @@ -92,6 +92,7 @@ public: Q_ENUM(Status) QQuickShaderEffect(QQuickItem *parent = nullptr); + ~QQuickShaderEffect() override; QByteArray fragmentShader() const; void setFragmentShader(const QByteArray &code); -- cgit v1.2.3 From 51696d5e8dbd17fe2bfdfc669bbf22e0e50af6c6 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 31 May 2019 16:21:28 +0200 Subject: Parser: Accept templated readonly properties Change-Id: I37d313e3156a44eb4487b1be007aa93ace18d882 Fixes: QTBUG-76018 Reviewed-by: Simon Hausmann --- src/qml/parser/qqmljs.g | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'src') diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index 27f23a6fa7..e549c4620a 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -1110,6 +1110,23 @@ UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T } break; ./ +UiObjectMember: T_READONLY T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_READONLY T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7)); + node->isReadonlyMember = true; + node->readonlyToken = loc(1); + node->typeModifier = stringRef(3); + node->propertyToken = loc(2); + node->typeModifierToken = loc(3); + node->typeToken = loc(5); + node->identifierToken = loc(7); + node->semicolonToken = loc(8); + sym(1).Node = node; + } break; +./ + UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_AUTOMATIC_SEMICOLON; UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_SEMICOLON; /. @@ -1221,6 +1238,34 @@ UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T } break; ./ +UiObjectMember: T_READONLY T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7)); + node->isReadonlyMember = true; + node->readonlyToken = loc(1); + node->typeModifier = stringRef(3); + node->propertyToken = loc(2); + node->typeModifierToken = loc(3); + node->typeToken = loc(5); + node->identifierToken = loc(7); + node->semicolonToken = loc(8); // insert a fake ';' before ':' + + AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(7)); + propertyName->identifierToken = loc(7); + propertyName->next = 0; + + AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(propertyName, sym(10).UiArrayMemberList->finish()); + binding->colonToken = loc(8); + binding->lbracketToken = loc(9); + binding->rbracketToken = loc(11); + + node->binding = binding; + + sym(1).Node = node; + } break; +./ + UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer; /. case $rule_number: { -- cgit v1.2.3 From 99c96eb1042575a7ca5ba534f453c679c6dc9cd8 Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 31 May 2019 19:01:07 +0200 Subject: Improve "Type error" when looking up a property of null or undefined Before: MenuItem.qml:98: TypeError: Type error After: MenuItem.qml:101: TypeError: Cannot read property 'height' of null The wording matches the similar error messages in qv4runtime.cpp. Change-Id: I3d9b3506195fe8e17e78117f2f51aba2adbc0564 Reviewed-by: Simon Hausmann Reviewed-by: Laurent Montel --- src/qml/jsruntime/qv4lookup.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index f8999342d1..6b8fb509a8 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -77,8 +77,13 @@ ReturnedValue Lookup::resolvePrimitiveGetter(ExecutionEngine *engine, const Valu primitiveLookup.type = object.type(); switch (primitiveLookup.type) { case Value::Undefined_Type: - case Value::Null_Type: - return engine->throwTypeError(); + case Value::Null_Type: { + Scope scope(engine); + ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]); + const QString message = QStringLiteral("Cannot read property '%1' of %2").arg(name->toQString()) + .arg(QLatin1String(primitiveLookup.type == Value::Undefined_Type ? "undefined" : "null")); + return engine->throwTypeError(message); + } case Value::Boolean_Type: primitiveLookup.proto = engine->booleanPrototype()->d(); break; -- cgit v1.2.3 From 56b0d420703e24523a6a06f75590f0480397f4d6 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Tue, 28 May 2019 23:29:41 +0900 Subject: Fix for loading translations automatically from resources When qml file is in resources, translations under i18n was not loaded Task-number: QTBUG-76085 Change-Id: I75315ceb6a1e6ab10309634a3c445a82476d525c Reviewed-by: Ulf Hermann --- src/qml/qml/qqmlapplicationengine.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index 1b7a433a84..facd79d211 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -76,7 +76,7 @@ void QQmlApplicationEnginePrivate::init() &QCoreApplication::exit, Qt::QueuedConnection); #if QT_CONFIG(translation) QTranslator* qtTranslator = new QTranslator; - if (qtTranslator->load(QLocale(), QLatin1String("qt"), QLatin1String("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + if (qtTranslator->load(QLocale(), QLatin1String("qt"), QLatin1String("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath), QLatin1String(".qm"))) QCoreApplication::installTranslator(qtTranslator); translators << qtTranslator; #endif @@ -90,10 +90,10 @@ void QQmlApplicationEnginePrivate::loadTranslations(const QUrl &rootFile) if (rootFile.scheme() != QLatin1String("file") && rootFile.scheme() != QLatin1String("qrc")) return; - QFileInfo fi(rootFile.toLocalFile()); + QFileInfo fi(QQmlFile::urlToLocalFileOrQrc(rootFile)); QTranslator *translator = new QTranslator; - if (translator->load(QLocale(), QLatin1String("qml"), QLatin1String("_"), fi.path() + QLatin1String("/i18n"))) { + if (translator->load(QLocale(), QLatin1String("qml"), QLatin1String("_"), fi.path() + QLatin1String("/i18n"), QLatin1String(".qm"))) { QCoreApplication::installTranslator(translator); translators << translator; } else { @@ -180,6 +180,9 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c) \list \li Connecting Qt.quit() to QCoreApplication::quit() \li Automatically loads translation files from an i18n directory adjacent to the main QML file. + \list + \li Translation files must have "qml_" prefix e.g. qml_ja_JP.qm. + \endlist \li Automatically sets an incubation controller if the scene contains a QQuickWindow. \li Automatically sets a \c QQmlFileSelector as the url interceptor, applying file selectors to all QML files and assets. -- cgit v1.2.3 From b1e9bc580adc1e7b3b1398f392016880dc5201ba Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Tue, 4 Jun 2019 10:50:28 +0200 Subject: Doc: Remove superfluous double quotes in code snippets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-75957 Change-Id: I2c9c70461a828978d1413b8cbdb407663b4b7493 Reviewed-by: Topi Reiniƶ --- src/qml/doc/snippets/qml/componentCreation.js | 4 ++-- src/qml/qml/qqmlcomponent.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/qml/doc/snippets/qml/componentCreation.js b/src/qml/doc/snippets/qml/componentCreation.js index 7364139d3d..ea45f18c37 100644 --- a/src/qml/doc/snippets/qml/componentCreation.js +++ b/src/qml/doc/snippets/qml/componentCreation.js @@ -17,7 +17,7 @@ function createSpriteObjects() { //![local] component = Qt.createComponent("Sprite.qml"); - sprite = component.createObject(appWindow, {"x": 100, "y": 100}); + sprite = component.createObject(appWindow, {x: 100, y: 100}); if (sprite == null) { // Error Handling @@ -32,7 +32,7 @@ function createSpriteObjects() { //![finishCreation] function finishCreation() { if (component.status == Component.Ready) { - sprite = component.createObject(appWindow, {"x": 100, "y": 100}); + sprite = component.createObject(appWindow, {x: 100, y: 100}); if (sprite == null) { // Error Handling console.log("Error creating object"); diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 57ea685a5d..a23a322df9 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1207,7 +1207,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent) \js var component = Qt.createComponent("Button.qml"); if (component.status == Component.Ready) - component.createObject(parent, {"x": 100, "y": 100}); + component.createObject(parent, {x: 100, y: 100}); \endjs Dynamically created instances can be deleted with the \c destroy() method. -- cgit v1.2.3 From 7940d57b53817f28e1a575a7c37aeed968fb2f61 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Fri, 24 May 2019 16:17:00 +0100 Subject: QQuickTableView: Don't try to forceLayout with no columns forceLayout is user invokable. If it's called before columns are loaded our call to firstColumn call QMap::firstKey will assert/crash. Insertion of columns later will trigger a layout. Change-Id: Id102e3ab4756ddd3f433037783dc70e1b29101c8 Reviewed-by: Richard Moe Gustavsen --- src/quick/items/qquicktableview.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index ac3397d2a9..83fa11a446 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -706,6 +706,9 @@ void QQuickTableViewPrivate::syncLoadedTableRectFromLoadedTable() void QQuickTableViewPrivate::forceLayout() { + if (loadedItems.isEmpty()) + return; + columnRowPositionsInvalid = true; clearEdgeSizeCache(); RebuildOptions rebuildOptions = RebuildOption::None; -- cgit v1.2.3 From 1aa4eab4a68e19702b5b3ab9b831efdc35266e66 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 13 May 2019 14:19:01 +0200 Subject: Fix heap-use-after-free with QQuickListView Ensure we stop FXViewItems from tracking so we don't have pointers to dead QQuickListViewPrivate object on QQuickItem destruction. Fixes: QTBUG-71581 Change-Id: I80291086697b1455d9319969fe5cba0ea4d04a73 Reviewed-by: Richard Moe Gustavsen --- src/quick/items/qquickgridview.cpp | 9 ++++++--- src/quick/items/qquickitemview.cpp | 15 ++++++++------- src/quick/items/qquickitemview_p_p.h | 4 ++-- src/quick/items/qquicklistview.cpp | 17 ++++++++++------- 4 files changed, 26 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index 6638fbd3e8..fecfa5fd2d 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -191,7 +191,7 @@ public: void resetFirstItemPosition(qreal pos = 0.0) override; void adjustFirstItem(qreal forwards, qreal backwards, int changeBeforeVisible) override; - void createHighlight() override; + void createHighlight(bool onDestruction = false) override; void updateHighlight() override; void resetHighlightPosition() override; @@ -696,9 +696,8 @@ void QQuickGridViewPrivate::adjustFirstItem(qreal forwards, qreal backwards, int gridItem->setPosition(gridItem->colPos(), gridItem->rowPos() + ((moveCount / columns) * rowSize())); } -void QQuickGridViewPrivate::createHighlight() +void QQuickGridViewPrivate::createHighlight(bool onDestruction) { - Q_Q(QQuickGridView); bool changed = false; if (highlight) { if (trackedItem == highlight) @@ -714,6 +713,10 @@ void QQuickGridViewPrivate::createHighlight() changed = true; } + if (onDestruction) + return; + + Q_Q(QQuickGridView); if (currentItem) { QQuickItem *item = createHighlightItem(); if (item) { diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 1f8a0de72b..431cb80a75 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -162,7 +162,7 @@ QQuickItemView::QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent) QQuickItemView::~QQuickItemView() { Q_D(QQuickItemView); - d->clear(); + d->clear(true); if (d->ownModel) delete d->model; delete d->header; @@ -1662,7 +1662,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) releaseItem(oldCurrentItem); } -void QQuickItemViewPrivate::clear() +void QQuickItemViewPrivate::clear(bool onDestruction) { Q_Q(QQuickItemView); currentChanges.reset(); @@ -1683,7 +1683,7 @@ void QQuickItemViewPrivate::clear() currentItem = nullptr; if (oldCurrentItem) emit q->currentItemChanged(); - createHighlight(); + createHighlight(onDestruction); trackedItem = nullptr; if (requestedIndex >= 0) { @@ -2352,15 +2352,16 @@ void QQuickItemView::destroyingItem(QObject *object) bool QQuickItemViewPrivate::releaseItem(FxViewItem *item) { Q_Q(QQuickItemView); - if (!item || !model) + if (!item) return true; if (trackedItem == item) trackedItem = nullptr; item->trackGeometry(false); - QQmlInstanceModel::ReleaseFlags flags = model->release(item->item); - if (item->item) { - if (flags == 0) { + QQmlInstanceModel::ReleaseFlags flags = {}; + if (model && item->item) { + flags = model->release(item->item); + if (!flags) { // item was not destroyed, and we no longer reference it. QQuickItemPrivate::get(item->item)->setCulled(true); unrequestedItems.insert(item->item, model->indexOf(item->item, q)); diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index ea5b5df9c6..170027de87 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -163,7 +163,7 @@ public: int mapFromModel(int modelIndex) const; virtual void init(); - virtual void clear(); + virtual void clear(bool onDestruction=false); virtual void updateViewport(); void regenerate(bool orientationChanged=false); @@ -327,7 +327,7 @@ protected: virtual bool hasStickyHeader() const { return false; } virtual bool hasStickyFooter() const { return false; } - virtual void createHighlight() = 0; + virtual void createHighlight(bool onDestruction = false) = 0; virtual void updateHighlight() = 0; virtual void resetHighlightPosition() = 0; virtual bool movingFromHighlight() { return false; } diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 81d019a26d..146917c679 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -81,7 +81,7 @@ public: FxViewItem *snapItemAt(qreal pos); void init() override; - void clear() override; + void clear(bool onDestruction) override; bool addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer) override; bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) override; @@ -98,7 +98,7 @@ public: void adjustFirstItem(qreal forwards, qreal backwards, int) override; void updateSizeChangesBeforeVisiblePos(FxViewItem *item, ChangeResult *removeResult) override; - void createHighlight() override; + void createHighlight(bool onDestruction = false) override; void updateHighlight() override; void resetHighlightPosition() override; bool movingFromHighlight() override; @@ -575,7 +575,7 @@ void QQuickListViewPrivate::init() ::memset(sectionCache, 0, sizeof(QQuickItem*) * sectionCacheSize); } -void QQuickListViewPrivate::clear() +void QQuickListViewPrivate::clear(bool onDestruction) { for (int i = 0; i < sectionCacheSize; ++i) { delete sectionCache[i]; @@ -587,7 +587,7 @@ void QQuickListViewPrivate::clear() releaseSectionItem(nextSectionItem); nextSectionItem = nullptr; lastVisibleSection = QString(); - QQuickItemViewPrivate::clear(); + QQuickItemViewPrivate::clear(onDestruction); } FxViewItem *QQuickListViewPrivate::newViewItem(int modelIndex, QQuickItem *item) @@ -634,7 +634,7 @@ void QQuickListViewPrivate::initializeViewItem(FxViewItem *item) bool QQuickListViewPrivate::releaseItem(FxViewItem *item) { if (!item || !model) - return true; + return QQuickItemViewPrivate::releaseItem(item); QPointer it = item->item; QQuickListViewAttached *att = static_cast(item->attached); @@ -876,9 +876,8 @@ void QQuickListViewPrivate::updateSizeChangesBeforeVisiblePos(FxViewItem *item, QQuickItemViewPrivate::updateSizeChangesBeforeVisiblePos(item, removeResult); } -void QQuickListViewPrivate::createHighlight() +void QQuickListViewPrivate::createHighlight(bool onDestruction) { - Q_Q(QQuickListView); bool changed = false; if (highlight) { if (trackedItem == highlight) @@ -896,6 +895,10 @@ void QQuickListViewPrivate::createHighlight() changed = true; } + if (onDestruction) + return; + + Q_Q(QQuickListView); if (currentItem) { QQuickItem *item = createHighlightItem(); if (item) { -- cgit v1.2.3