diff options
author | Liang Qi <liang.qi@qt.io> | 2016-08-13 00:41:58 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-08-13 00:41:58 +0200 |
commit | d54d28981c90d23d7fa0cfc5a9e3049e3e4df6b5 (patch) | |
tree | 0eb2f54f16b014f6eaa362095393d1bd058adb52 | |
parent | 580f2872f09cf7ad83ec9ae5dca686683a3cac80 (diff) | |
parent | 6f15de1d2da9c83d7fca1d5c8243c0d69a1390ee (diff) |
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts:
src/qml/compiler/qv4isel_moth.cpp
src/qml/compiler/qv4ssa_p.h
tests/benchmarks/qml/qqmlimage/qqmlimage.pro
tests/benchmarks/qml/qqmlimage/tst_qqmlimage.cpp
Change-Id: Iad11ce7fdf0c6d200fdebc16a94081bd8069a87a
34 files changed, 644 insertions, 582 deletions
diff --git a/examples/quick/scenegraph/graph/linenode.cpp b/examples/quick/scenegraph/graph/linenode.cpp index 473be7da17..992e2d44c9 100644 --- a/examples/quick/scenegraph/graph/linenode.cpp +++ b/examples/quick/scenegraph/graph/linenode.cpp @@ -56,7 +56,7 @@ class LineShader : public QSGSimpleMaterialShader<LineMaterial> QSG_DECLARE_SIMPLE_SHADER(LineShader, LineMaterial) public: - LineShader() { + LineShader() : id_color(-1), id_spread(-1), id_size(-1) { setShaderSourceFile(QOpenGLShader::Vertex, ":/scenegraph/graph/shaders/line.vsh"); setShaderSourceFile(QOpenGLShader::Fragment, ":/scenegraph/graph/shaders/line.fsh"); } diff --git a/examples/quick/scenegraph/graph/noisynode.cpp b/examples/quick/scenegraph/graph/noisynode.cpp index bc273cf632..834151599b 100644 --- a/examples/quick/scenegraph/graph/noisynode.cpp +++ b/examples/quick/scenegraph/graph/noisynode.cpp @@ -61,7 +61,7 @@ class NoisyShader : public QSGSimpleMaterialShader<NoisyMaterial> QSG_DECLARE_SIMPLE_SHADER(NoisyShader, NoisyMaterial) public: - NoisyShader() { + NoisyShader() : id_color(-1), id_texture(-1), id_textureSize(-1) { setShaderSourceFile(QOpenGLShader::Vertex, ":/scenegraph/graph/shaders/noisy.vsh"); setShaderSourceFile(QOpenGLShader::Fragment, ":/scenegraph/graph/shaders/noisy.fsh"); } diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index f49996a3b8..caa4a55d3d 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -1420,7 +1420,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI continue; QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType); - const QMetaObject *mo = pc->firstCppMetaObject(); + const QMetaObject *mo = pc ? pc->firstCppMetaObject() : 0; while (mo) { if (mo == &QQmlComponent::staticMetaObject) break; diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index be10d50e9b..e84b9c6ec9 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -149,167 +149,6 @@ inline bool isBoolType(IR::Expr *e) return (e->type == IR::BoolType); } -/* - * stack slot allocation: - * - * foreach bb do - * foreach stmt do - * if the current statement is not a phi-node: - * purge ranges that end before the current statement - * check for life ranges to activate, and if they don't have a stackslot associated then allocate one - * renumber temps to stack - * for phi nodes: check if all temps (src+dst) are assigned stack slots and marked as allocated - * if it's a jump: - * foreach phi node in the successor: - * allocate slots for each temp (both sources and targets) if they don't have one allocated already - * insert moves before the jump - */ -class AllocateStackSlots: protected ConvertTemps -{ - IR::LifeTimeIntervals::Ptr _intervals; - QVector<IR::LifeTimeInterval *> _unhandled; - QVector<IR::LifeTimeInterval *> _live; - QBitArray _slotIsInUse; - IR::Function *_function; - - int defPosition(IR::Stmt *s) const - { - return usePosition(s) + 1; - } - - int usePosition(IR::Stmt *s) const - { - return _intervals->positionForStatement(s); - } - -public: - AllocateStackSlots(const IR::LifeTimeIntervals::Ptr &intervals) - : _intervals(intervals) - , _slotIsInUse(intervals->size(), false) - , _function(0) - { - _live.reserve(8); - _unhandled = _intervals->intervals(); - } - - void forFunction(IR::Function *function) - { - IR::Optimizer::showMeTheCode(function, "Before stack slot allocation"); - _function = function; - toStackSlots(function); - } - -protected: - virtual int allocateFreeSlot() - { - for (int i = 0, ei = _slotIsInUse.size(); i != ei; ++i) { - if (!_slotIsInUse[i]) { - if (_nextUnusedStackSlot <= i) { - Q_ASSERT(_nextUnusedStackSlot == i); - _nextUnusedStackSlot = i + 1; - } - _slotIsInUse[i] = true; - return i; - } - } - - Q_UNREACHABLE(); - return -1; - } - - virtual void process(IR::Stmt *s) - { -// qDebug("L%d statement %d:", _currentBasicBlock->index, s->id); - - if (IR::Phi *phi = s->asPhi()) { - visitPhi(phi); - } else { - // purge ranges no longer alive: - for (int i = 0; i < _live.size(); ) { - const IR::LifeTimeInterval *lti = _live.at(i); - if (lti->end() < usePosition(s)) { -// qDebug() << "\t - moving temp" << lti->temp().index << "to handled, freeing slot" << _stackSlotForTemp[lti->temp().index]; - _live.remove(i); - Q_ASSERT(_slotIsInUse[_stackSlotForTemp[lti->temp().index]]); - _slotIsInUse[_stackSlotForTemp[lti->temp().index]] = false; - continue; - } else { - ++i; - } - } - - // active new ranges: - while (!_unhandled.isEmpty()) { - IR::LifeTimeInterval *lti = _unhandled.last(); - if (lti->start() > defPosition(s)) - break; // we're done - Q_ASSERT(!_stackSlotForTemp.contains(lti->temp().index)); - _stackSlotForTemp[lti->temp().index] = allocateFreeSlot(); -// qDebug() << "\t - activating temp" << lti->temp().index << "on slot" << _stackSlotForTemp[lti->temp().index]; - _live.append(lti); - _unhandled.removeLast(); - } - - s->accept(this); - } - - if (IR::Jump *jump = s->asJump()) { - IR::MoveMapping moves; - for (IR::Stmt *succStmt : jump->target->statements()) { - if (IR::Phi *phi = succStmt->asPhi()) { - forceActivation(*phi->targetTemp); - for (int i = 0, ei = phi->incoming.size(); i != ei; ++i) { - IR::Expr *e = phi->incoming[i]; - if (IR::Temp *t = e->asTemp()) { - forceActivation(*t); - } - if (jump->target->in[i] == _currentBasicBlock) - moves.add(phi->incoming[i], phi->targetTemp); - } - } else { - break; - } - } - moves.order(); - QList<IR::Move *> newMoves = moves.insertMoves(_currentBasicBlock, _function, true); - foreach (IR::Move *move, newMoves) - move->accept(this); - } - } - - void forceActivation(const IR::Temp &t) - { - if (_stackSlotForTemp.contains(t.index)) - return; - - int i = _unhandled.size() - 1; - for (; i >= 0; --i) { - IR::LifeTimeInterval *lti = _unhandled[i]; - if (lti->temp() == t) { - _live.append(lti); - _unhandled.remove(i); - break; - } - } - Q_ASSERT(i >= 0); // check that we always found the entry - - _stackSlotForTemp[t.index] = allocateFreeSlot(); -// qDebug() << "\t - force activating temp" << t.index << "on slot" << _stackSlotForTemp[t.index]; - } - - virtual void visitPhi(IR::Phi *phi) - { - Q_UNUSED(phi); -#if !defined(QT_NO_DEBUG) - Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index)); - Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]); - foreach (IR::Expr *e, phi->incoming) { - if (IR::Temp *t = e->asTemp()) - Q_ASSERT(_stackSlotForTemp.contains(t->index)); - } -#endif // defined(QT_NO_DEBUG) - } -}; } // anonymous namespace InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator) @@ -359,7 +198,7 @@ void InstructionSelection::run(int functionIndex) qEnvironmentVariableIsEmpty("QV4_NO_INTERPRETER_STACK_SLOT_ALLOCATION"); if (doStackSlotAllocation) { - AllocateStackSlots(opt.lifeTimeIntervals()).forFunction(_function); + IR::AllocateStackSlots(opt.lifeTimeIntervals()).forFunction(_function); } else { opt.convertOutOfSSA(); ConvertTemps().toStackSlots(_function); diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h index e608c08591..5d4b12e275 100644 --- a/src/qml/compiler/qv4ssa_p.h +++ b/src/qml/compiler/qv4ssa_p.h @@ -52,6 +52,7 @@ // #include "qv4jsir_p.h" +#include "qv4isel_util_p.h" #include <QtCore/QSharedPointer> QT_BEGIN_NAMESPACE @@ -277,6 +278,168 @@ private: QList<Move> &swaps) const; }; +/* + * stack slot allocation: + * + * foreach bb do + * foreach stmt do + * if the current statement is not a phi-node: + * purge ranges that end before the current statement + * check for life ranges to activate, and if they don't have a stackslot associated then allocate one + * renumber temps to stack + * for phi nodes: check if all temps (src+dst) are assigned stack slots and marked as allocated + * if it's a jump: + * foreach phi node in the successor: + * allocate slots for each temp (both sources and targets) if they don't have one allocated already + * insert moves before the jump + */ +class AllocateStackSlots: protected ConvertTemps +{ + IR::LifeTimeIntervals::Ptr _intervals; + QVector<IR::LifeTimeInterval *> _unhandled; + QVector<IR::LifeTimeInterval *> _live; + QBitArray _slotIsInUse; + IR::Function *_function; + + int defPosition(IR::Stmt *s) const + { + return usePosition(s) + 1; + } + + int usePosition(IR::Stmt *s) const + { + return _intervals->positionForStatement(s); + } + +public: + AllocateStackSlots(const IR::LifeTimeIntervals::Ptr &intervals) + : _intervals(intervals) + , _slotIsInUse(intervals->size(), false) + , _function(0) + { + _live.reserve(8); + _unhandled = _intervals->intervals(); + } + + void forFunction(IR::Function *function) + { + IR::Optimizer::showMeTheCode(function, "Before stack slot allocation"); + _function = function; + toStackSlots(function); + } + +protected: + virtual int allocateFreeSlot() + { + for (int i = 0, ei = _slotIsInUse.size(); i != ei; ++i) { + if (!_slotIsInUse[i]) { + if (_nextUnusedStackSlot <= i) { + Q_ASSERT(_nextUnusedStackSlot == i); + _nextUnusedStackSlot = i + 1; + } + _slotIsInUse[i] = true; + return i; + } + } + + Q_UNREACHABLE(); + return -1; + } + + virtual void process(IR::Stmt *s) + { +// qDebug("L%d statement %d:", _currentBasicBlock->index, s->id); + + if (IR::Phi *phi = s->asPhi()) { + visitPhi(phi); + } else { + // purge ranges no longer alive: + for (int i = 0; i < _live.size(); ) { + const IR::LifeTimeInterval *lti = _live.at(i); + if (lti->end() < usePosition(s)) { +// qDebug() << "\t - moving temp" << lti->temp().index << "to handled, freeing slot" << _stackSlotForTemp[lti->temp().index]; + _live.remove(i); + Q_ASSERT(_slotIsInUse[_stackSlotForTemp[lti->temp().index]]); + _slotIsInUse[_stackSlotForTemp[lti->temp().index]] = false; + continue; + } else { + ++i; + } + } + + // active new ranges: + while (!_unhandled.isEmpty()) { + IR::LifeTimeInterval *lti = _unhandled.last(); + if (lti->start() > defPosition(s)) + break; // we're done + Q_ASSERT(!_stackSlotForTemp.contains(lti->temp().index)); + _stackSlotForTemp[lti->temp().index] = allocateFreeSlot(); +// qDebug() << "\t - activating temp" << lti->temp().index << "on slot" << _stackSlotForTemp[lti->temp().index]; + _live.append(lti); + _unhandled.removeLast(); + } + + s->accept(this); + } + + if (IR::Jump *jump = s->asJump()) { + IR::MoveMapping moves; + for (IR::Stmt *succStmt : jump->target->statements()) { + if (IR::Phi *phi = succStmt->asPhi()) { + forceActivation(*phi->targetTemp); + for (int i = 0, ei = phi->incoming.size(); i != ei; ++i) { + IR::Expr *e = phi->incoming[i]; + if (IR::Temp *t = e->asTemp()) { + forceActivation(*t); + } + if (jump->target->in[i] == _currentBasicBlock) + moves.add(phi->incoming[i], phi->targetTemp); + } + } else { + break; + } + } + moves.order(); + QList<IR::Move *> newMoves = moves.insertMoves(_currentBasicBlock, _function, true); + foreach (IR::Move *move, newMoves) + move->accept(this); + } + } + + void forceActivation(const IR::Temp &t) + { + if (_stackSlotForTemp.contains(t.index)) + return; + + int i = _unhandled.size() - 1; + for (; i >= 0; --i) { + IR::LifeTimeInterval *lti = _unhandled[i]; + if (lti->temp() == t) { + _live.append(lti); + _unhandled.remove(i); + break; + } + } + Q_ASSERT(i >= 0); // check that we always found the entry + + _stackSlotForTemp[t.index] = allocateFreeSlot(); +// qDebug() << "\t - force activating temp" << t.index << "on slot" << _stackSlotForTemp[t.index]; + } + + virtual void visitPhi(IR::Phi *phi) + { + Q_UNUSED(phi); +#if !defined(QT_NO_DEBUG) + Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index)); + Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]); + foreach (IR::Expr *e, phi->incoming) { + if (IR::Temp *t = e->asTemp()) + Q_ASSERT(_stackSlotForTemp.contains(t->index)); + } +#endif // defined(QT_NO_DEBUG) + } +}; + } // IR namespace } // QV4 namespace diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc index de8b967d72..1e33f2f641 100644 --- a/src/qml/doc/src/javascript/hostenvironment.qdoc +++ b/src/qml/doc/src/javascript/hostenvironment.qdoc @@ -80,7 +80,10 @@ Note that QML makes the following modifications to native objects: QML implements the following restrictions for JavaScript code: \list -\li JavaScript code cannot modify the global object. +\li JavaScript code written in a \c .qml file cannot modify the global object. + JavaScript code in a .js file can modify the global object, + and those modifications will be visible to the .qml file when + \l {Importing a JavaScript Resource from a QML Document}{imported}. In QML, the global object is constant - existing properties cannot be modified or deleted, and no new properties may be created. diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 15a4ed2e56..26f473a7aa 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1131,8 +1131,13 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return value.integerValue(); if (value.isNumber()) return value.asDouble(); - if (value.isString()) - return value.stringValue()->toQString(); + if (value.isString()) { + const QString &str = value.toQString(); + // QChars are stored as a strings + if (typeHint == QVariant::Char && str.size() == 1) + return str.at(0); + return str; + } if (const QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>()) return ld->d()->locale; if (const QV4::DateObject *d = value.as<DateObject>()) @@ -1272,9 +1277,9 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) case QMetaType::UShort: return QV4::Encode((int)*reinterpret_cast<const unsigned short*>(ptr)); case QMetaType::Char: - return newString(QChar::fromLatin1(*reinterpret_cast<const char *>(ptr)))->asReturnedValue(); + return QV4::Encode((int)*reinterpret_cast<const char*>(ptr)); case QMetaType::UChar: - return newString(QChar::fromLatin1(*reinterpret_cast<const unsigned char *>(ptr)))->asReturnedValue(); + return QV4::Encode((int)*reinterpret_cast<const unsigned char*>(ptr)); case QMetaType::QChar: return newString(*reinterpret_cast<const QChar *>(ptr))->asReturnedValue(); case QMetaType::QDateTime: diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index f57d9059e3..3ebe074ae3 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -434,7 +434,7 @@ void MemoryManager::sweep(bool lastSweep) Managed *m = (*it).as<Managed>(); if (m->markBit()) continue; - // we need to call detroyObject on qobjectwrappers now, so that they can emit the destroyed + // we need to call destroyObject on qobjectwrappers now, so that they can emit the destroyed // signal before we start sweeping the heap if (QObjectWrapper *qobjectWrapper = (*it).as<QObjectWrapper>()) qobjectWrapper->destroyObject(lastSweep); @@ -442,6 +442,17 @@ void MemoryManager::sweep(bool lastSweep) (*it) = Primitive::undefinedValue(); } + // onDestruction handlers may have accessed other QObject wrappers and reset their value, so ensure + // that they are all set to undefined. + for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) { + if (!(*it).isManaged()) + continue; + Managed *m = (*it).as<Managed>(); + if (m->markBit()) + continue; + (*it) = Primitive::undefinedValue(); + } + // Now it is time to free QV4::QObjectWrapper Value, we must check the Value's tag to make sure its object has been destroyed const int pendingCount = m_pendingFreedObjectWrapperValue.count(); if (pendingCount) { diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 831965f36a..19e259207c 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -75,12 +75,12 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile , resolvedTypes(compiledData->resolvedTypes) , propertyCaches(compiledData->propertyCaches) , vmeMetaObjectData(compiledData->metaObjects) + , sharedState(new QQmlObjectCreatorSharedState) + , topLevelCreator(true) , activeVMEDataForRootContext(activeVMEDataForRootContext) { init(parentContext); - sharedState = new QQmlObjectCreatorSharedState; - topLevelCreator = true; sharedState->componentAttached = 0; sharedState->allCreatedBindings.allocate(compiledData->totalBindingsCount); sharedState->allParserStatusCallbacks.allocate(compiledData->totalParserStatusCount); @@ -100,12 +100,11 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile , resolvedTypes(compiledData->resolvedTypes) , propertyCaches(compiledData->propertyCaches) , vmeMetaObjectData(compiledData->metaObjects) + , sharedState(inheritedSharedState) + , topLevelCreator(false) , activeVMEDataForRootContext(0) { init(parentContext); - - sharedState = inheritedSharedState; - topLevelCreator = false; } void QQmlObjectCreator::init(QQmlContextData *providedParentContext) @@ -121,6 +120,7 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext) context = 0; _qobject = 0; _scopeObject = 0; + _bindingTarget = 0; _valueTypeProperty = 0; _compiledObject = 0; _compiledObjectIndex = -1; diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index df2ff05de1..0ef0a5b16e 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1334,29 +1334,8 @@ bool QQmlPropertyPrivate::write(QObject *object, bool ok = false; QVariant v; - if (variantType == QVariant::String) { - const QString &str = value.toString(); - const bool targetIsChar = (propertyType == qMetaTypeId<QChar>() - || propertyType == qMetaTypeId<char>() - || propertyType == qMetaTypeId<unsigned char>()); - // If the string contains only one character and the target is a char, try converting it. - if (targetIsChar) { - if (str.size() != 1) - return false; // We can only convert if the string contains exactly one character. - - const QChar &qChar = str.at(0); - if (propertyType == qMetaTypeId<QChar>()) { - v = qChar; - ok = true; - } else if (propertyType == qMetaTypeId<char>() || propertyType == qMetaTypeId<unsigned char>()) { - const char c = qChar.toLatin1(); - v = c; - ok = (qChar == c); - } - } else { - v = QQmlStringConverters::variantFromString(str, propertyType, &ok); - } - } + if (variantType == QVariant::String) + v = QQmlStringConverters::variantFromString(value.toString(), propertyType, &ok); if (!ok) { v = value; diff --git a/src/quick/items/qquickclipnode.cpp b/src/quick/items/qquickclipnode.cpp index 1114686a9a..56f8227c05 100644 --- a/src/quick/items/qquickclipnode.cpp +++ b/src/quick/items/qquickclipnode.cpp @@ -93,7 +93,7 @@ void QQuickDefaultClipNode::updateGeometry() int segments = qMin(30, qCeil(radius)); // Number of segments per corner. - g->allocate((segments + 1) * 2); + g->allocate((segments + 1) * 4); QVector2D *vertices = (QVector2D *)g->vertexData(); diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index f72923a0d5..03b2a8128c 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1234,13 +1234,17 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event) return; qint64 currentTimestamp = computeCurrentTime(event); - qreal elapsed = qreal(currentTimestamp - (lastPos.isNull() ? lastPressTime : lastPosTime)) / 1000.; QVector2D deltas = QVector2D(event->localPos() - pressPos); bool overThreshold = false; QVector2D velocity = QGuiApplicationPrivate::mouseEventVelocity(event); // TODO guarantee that events always have velocity so that it never needs to be computed here - if (!(QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity)) + if (!(QGuiApplicationPrivate::mouseEventCaps(event) & QTouchDevice::Velocity)) { + qint64 lastTimestamp = (lastPos.isNull() ? lastPressTime : lastPosTime); + if (currentTimestamp == lastTimestamp) + return; // events are too close together: velocity would be infinite + qreal elapsed = qreal(currentTimestamp - lastTimestamp) / 1000.; velocity = QVector2D(event->localPos() - (lastPos.isNull() ? pressPos : lastPos)) / elapsed; + } if (q->yflick()) overThreshold |= QQuickWindowPrivate::dragOverThreshold(deltas.y(), Qt::YAxis, event); diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index c7e476c4b5..0c3f5a6974 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -296,6 +296,8 @@ qreal QQuickPathViewPrivate::positionOfIndex(qreal index) const // account the circular space. bool QQuickPathViewPrivate::isInBound(qreal position, qreal lower, qreal upper) const { + if (lower == upper) + return true; if (lower > upper) { if (position > upper && position > lower) position -= mappedRange; @@ -1903,6 +1905,14 @@ void QQuickPathView::updatePolish() refill(); } +static inline int currentIndexRemainder(int currentIndex, int modelCount) Q_DECL_NOTHROW +{ + if (currentIndex < 0) + return modelCount + currentIndex % modelCount; + else + return currentIndex % modelCount; +} + void QQuickPathView::componentComplete() { Q_D(QQuickPathView); @@ -1914,7 +1924,7 @@ void QQuickPathView::componentComplete() if (d->model) { d->modelCount = d->model->count(); if (d->modelCount && d->currentIndex != 0) // an initial value has been provided for currentIndex - d->offset = qmlMod(d->modelCount - d->currentIndex, d->modelCount); + d->offset = qmlMod(d->modelCount - currentIndexRemainder(d->currentIndex, d->modelCount), d->modelCount); } d->createHighlight(); @@ -1988,7 +1998,8 @@ void QQuickPathView::refill() qreal endPos; int startIdx = 0; qreal startPos = 0.0; - if (d->items.count()) { + const bool wasEmpty = d->items.isEmpty(); + if (!wasEmpty) { //Find the beginning and end, items may not be in sorted order endPos = -1.0; startPos = 2.0; @@ -2047,7 +2058,8 @@ void QQuickPathView::refill() } //Prepend - idx = startIdx - 1; + idx = (wasEmpty ? d->calcCurrentIndex() : startIdx) - 1; + if (idx < 0) idx = d->modelCount - 1; nextPos = d->positionOfIndex(idx); @@ -2086,27 +2098,33 @@ void QQuickPathView::refill() idx = startIdx; QQuickItem *lastItem = d->items[0]; while (idx != endIdx) { - //This gets the reference from the delegate model, and will not re-create - QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0); - if (!item) { - waiting = true; - break; - } - if (!d->items.contains(item)) { //We found a hole - nextPos = d->positionOfIndex(idx); - qCDebug(lcItemViewDelegateLifecycle) << "middle insert" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count(); - if (d->currentIndex == idx) { - currentVisible = true; - d->currentItemOffset = nextPos; + nextPos = d->positionOfIndex(idx); + if (d->isInBound(nextPos, d->mappedRange - d->mappedCache, 1.0 + d->mappedCache)) { + //This gets the reference from the delegate model, and will not re-create + QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0); + if (!item) { + waiting = true; + break; } - int lastListIdx = d->items.indexOf(lastItem); - d->items.insert(lastListIdx + 1, item); - d->updateItem(item, nextPos); - } else { - d->releaseItem(item); + + if (!d->items.contains(item)) { //We found a hole + qCDebug(lcItemViewDelegateLifecycle) << "middle insert" << idx << "@" << nextPos + << (d->currentIndex == idx ? "current" : "") + << "items count was" << d->items.count(); + if (d->currentIndex == idx) { + currentVisible = true; + d->currentItemOffset = nextPos; + } + int lastListIdx = d->items.indexOf(lastItem); + d->items.insert(lastListIdx + 1, item); + d->updateItem(item, nextPos); + } else { + d->releaseItem(item); + } + + lastItem = item; } - lastItem = item; ++idx; if (idx >= d->modelCount) idx = 0; diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 59331647e5..8288554028 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -2028,6 +2028,7 @@ void QQuickText::setTextFormat(TextFormat format) } d->updateLayout(); setAcceptHoverEvents(d->richText || d->styledText); + setAcceptedMouseButtons(d->richText || d->styledText ? Qt::LeftButton : Qt::NoButton); emit textFormatChanged(d->format); } diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp index b28ca7725a..bb4a3b04d5 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp @@ -259,7 +259,8 @@ void QSGDefaultDistanceFieldGlyphCache::createTexture(TextureInfo *texInfo, int const GLenum format = GL_ALPHA; #endif - m_funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, 0); + QByteArray zeroBuf(width * height, 0); + m_funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, zeroBuf.constData()); texInfo->size = QSize(width, height); diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp index e0cde6c86f..f49fd391ac 100644 --- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp +++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp @@ -61,6 +61,7 @@ private slots: void qtbug_22535(); void evalAfterInvalidate(); void qobjectDerived(); + void qtbug_49232(); private: QQmlEngine engine; @@ -200,6 +201,8 @@ class TestObject : public QObject Q_PROPERTY(int a READ a NOTIFY aChanged) Q_PROPERTY(int b READ b NOTIFY bChanged) Q_PROPERTY(int c READ c NOTIFY cChanged) + Q_PROPERTY(char d READ d NOTIFY dChanged) + Q_PROPERTY(uchar e READ e NOTIFY eChanged) public: TestObject() : _a(10), _b(10), _c(10) {} @@ -213,15 +216,25 @@ public: int c() const { return _c; } void setC(int c) { _c = c; emit cChanged(); } + char d() const { return _d; } + void setD(char d) { _d = d; emit dChanged(); } + + uchar e() const { return _e; } + void setE(uchar e) { _e = e; emit eChanged(); } + signals: void aChanged(); void bChanged(); void cChanged(); + void dChanged(); + void eChanged(); private: int _a; int _b; int _c; + char _d; + uchar _e; }; #define TEST_CONTEXT_PROPERTY(ctxt, name, value) \ @@ -694,6 +707,22 @@ void tst_qqmlcontext::qobjectDerived() QCOMPARE(command.count, 2); } +void tst_qqmlcontext::qtbug_49232() +{ + TestObject testObject; + testObject.setD('a'); + testObject.setE(97); + + QQmlEngine engine; + engine.rootContext()->setContextProperty("TestObject", &testObject); + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { property int valueOne: TestObject.d; property int valueTwo: TestObject.e }", QUrl()); + QScopedPointer<QObject> obj(component.create()); + + QCOMPARE(obj->property("valueOne"), QVariant('a')); + QCOMPARE(obj->property("valueTwo"), QVariant(97)); +} + QTEST_MAIN(tst_qqmlcontext) #include "tst_qqmlcontext.moc" diff --git a/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml b/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml new file mode 100644 index 0000000000..8bb0a3554e --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml @@ -0,0 +1,3 @@ +import Test 1.0 +WeakReferenceMutator { +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 2c9f08c82a..b6d2e303cb 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -44,6 +44,8 @@ #include <private/qv4scopedvalue_p.h> #include <private/qv4alloca_p.h> #include <private/qv4runtime_p.h> +#include <private/qv4object_p.h> +#include <private/qqmlcomponentattached_p.h> #ifdef Q_CC_MSVC #define NO_INLINE __declspec(noinline) @@ -282,6 +284,7 @@ private slots: void replaceBinding(); void deleteRootObjectInCreation(); void onDestruction(); + void onDestructionViaGC(); void bindingSuppression(); void signalEmitted(); void threadSignal(); @@ -7150,6 +7153,105 @@ void tst_qqmlecmascript::onDestruction() } } +class WeakReferenceMutator : public QObject +{ + Q_OBJECT +public: + WeakReferenceMutator() + : resultPtr(Q_NULLPTR) + , weakRef(Q_NULLPTR) + {} + + void init(QV4::ExecutionEngine *v4, QV4::WeakValue *weakRef, bool *resultPtr) + { + QV4::QObjectWrapper::wrap(v4, this); + QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); + + this->resultPtr = resultPtr; + this->weakRef = weakRef; + + QObject::connect(QQmlComponent::qmlAttachedProperties(this), &QQmlComponentAttached::destruction, this, &WeakReferenceMutator::reviveFirstWeakReference); + } + +private slots: + void reviveFirstWeakReference() { + *resultPtr = weakRef->valueRef() && weakRef->isNullOrUndefined(); + if (!*resultPtr) + return; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine(this)); + weakRef->set(v4, v4->newObject()); + *resultPtr = weakRef->valueRef() && !weakRef->isNullOrUndefined(); + } + +public: + bool *resultPtr; + + QV4::WeakValue *weakRef; +}; + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +namespace Heap { +struct WeakReferenceSentinel : public Object { + WeakReferenceSentinel(WeakValue *weakRef, bool *resultPtr) + : weakRef(weakRef) + , resultPtr(resultPtr) { + + } + + ~WeakReferenceSentinel() { + *resultPtr = weakRef->isNullOrUndefined(); + } + + WeakValue *weakRef; + bool *resultPtr; +}; +} // namespace Heap + +struct WeakReferenceSentinel : public Object { + V4_OBJECT2(WeakReferenceSentinel, Object) + V4_NEEDS_DESTROY +}; + +} // namespace QV4 + +QT_END_NAMESPACE + +DEFINE_OBJECT_VTABLE(QV4::WeakReferenceSentinel); + +void tst_qqmlecmascript::onDestructionViaGC() +{ + qmlRegisterType<WeakReferenceMutator>("Test", 1, 0, "WeakReferenceMutator"); + + QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); + + QQmlComponent component(&engine, testFileUrl("DestructionHelper.qml")); + + QScopedPointer<QV4::WeakValue> weakRef; + + bool mutatorResult = false; + bool sentinelResult = false; + + { + weakRef.reset(new QV4::WeakValue); + weakRef->set(v4, v4->newObject()); + QVERIFY(!weakRef->isNullOrUndefined()); + + QPointer<WeakReferenceMutator> weakReferenceMutator = qobject_cast<WeakReferenceMutator *>(component.create()); + QVERIFY2(!weakReferenceMutator.isNull(), qPrintable(component.errorString())); + weakReferenceMutator->init(v4, weakRef.data(), &mutatorResult); + + v4->memoryManager->allocObject<QV4::WeakReferenceSentinel>(weakRef.data(), &sentinelResult); + } + gc(engine); + + QVERIFY2(mutatorResult, "We failed to re-assign the weak reference a new value during GC"); + QVERIFY2(sentinelResult, "The weak reference was not cleared properly"); +} + struct EventProcessor : public QObject { Q_OBJECT diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index e140747881..1d01f69d9b 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -326,11 +326,8 @@ class PropertyObject : public QObject Q_PROPERTY(MyQmlObject *qmlObject READ qmlObject) Q_PROPERTY(MyQObject *qObject READ qObject WRITE setQObject NOTIFY qObjectChanged) Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty) - Q_PROPERTY(char charProperty READ charProperty WRITE setCharProperty) Q_PROPERTY(QChar qcharProperty READ qcharProperty WRITE setQcharProperty) Q_PROPERTY(QChar constQChar READ constQChar STORED false CONSTANT FINAL) - Q_PROPERTY(char constChar READ constChar STORED false CONSTANT FINAL) - Q_PROPERTY(int constInt READ constInt STORED false CONSTANT FINAL) Q_CLASSINFO("DefaultProperty", "defaultProperty") public: @@ -367,15 +364,11 @@ public: } QString stringProperty() const { return m_stringProperty;} - char charProperty() const { return m_charProperty; } QChar qcharProperty() const { return m_qcharProperty; } QChar constQChar() const { return 0x25cf; /* Unicode: black circle */ } - char constChar() const { return 'A'; } - int constInt() const { return 123456; } void setStringProperty(QString arg) { m_stringProperty = arg; } - void setCharProperty(char arg) { m_charProperty = arg; } void setQcharProperty(QChar arg) { m_qcharProperty = arg; } signals: @@ -392,7 +385,6 @@ private: MyQmlObject m_qmlObject; MyQObject *m_qObject; QString m_stringProperty; - char m_charProperty; QChar m_qcharProperty; }; @@ -1405,23 +1397,14 @@ void tst_qqmlproperty::write() // Char/string-property { PropertyObject o; - QQmlProperty charProperty(&o, "charProperty"); QQmlProperty qcharProperty(&o, "qcharProperty"); QQmlProperty stringProperty(&o, "stringProperty"); const int black_circle = 0x25cf; - QCOMPARE(charProperty.write(QString("foo")), false); - QCOMPARE(charProperty.write('Q'), true); - QCOMPARE(charProperty.read(), QVariant('Q')); - QCOMPARE(charProperty.write(QString("t")), true); - QCOMPARE(charProperty.read(), QVariant('t')); - QCOMPARE(qcharProperty.write(QString("foo")), false); QCOMPARE(qcharProperty.write('Q'), true); QCOMPARE(qcharProperty.read(), QVariant('Q')); - QCOMPARE(qcharProperty.write(QString("t")), true); - QCOMPARE(qcharProperty.read(), QVariant('t')); QCOMPARE(qcharProperty.write(QChar(black_circle)), true); QCOMPARE(qcharProperty.read(), QVariant(QChar(black_circle))); @@ -1430,19 +1413,10 @@ void tst_qqmlproperty::write() QCOMPARE(o.stringProperty(), QString("bar")); QCOMPARE(stringProperty.write(QVariant(1234)), true); QCOMPARE(stringProperty.read().toString(), QString::number(1234)); + QCOMPARE(stringProperty.write('A'), true); + QCOMPARE(stringProperty.read().toString(), QString::number('A')); QCOMPARE(stringProperty.write(QChar(black_circle)), true); - QCOMPARE(stringProperty.read(), QVariant(QString(QChar(black_circle)))); - - { // char -> QString - QQmlComponent component(&engine); - component.setData("import Test 1.0\nPropertyObject { stringProperty: constChar }", QUrl()); - PropertyObject *obj = qobject_cast<PropertyObject*>(component.create()); - QVERIFY(obj != 0); - if (obj) { - QQmlProperty stringProperty(obj, "stringProperty"); - QCOMPARE(stringProperty.read(), QVariant(QString(obj->constChar()))); - } - } + QCOMPARE(stringProperty.read(), QVariant(QChar(black_circle))); { // QChar -> QString QQmlComponent component(&engine); @@ -1455,16 +1429,6 @@ void tst_qqmlproperty::write() } } - { // int -> QString - QQmlComponent component(&engine); - component.setData("import Test 1.0\nPropertyObject { stringProperty: constInt }", QUrl()); - PropertyObject *obj = qobject_cast<PropertyObject*>(component.create()); - QVERIFY(obj != 0); - if (obj) { - QQmlProperty stringProperty(obj, "stringProperty"); - QCOMPARE(stringProperty.read(), QVariant(QString::number(obj->constInt()))); - } - } } // VariantMap-property diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml index 98d7ea4cb7..65f736f305 100644 --- a/tests/auto/qmltest/listview/tst_listview.qml +++ b/tests/auto/qmltest/listview/tst_listview.qml @@ -320,9 +320,13 @@ Item { function test_listInteractiveCurrentIndexEnforce() { mousePress(listInteractiveCurrentIndexEnforce, 10, 50); + wait(1); // because Flickable pays attention to velocity, we need some time between movements mouseMove(listInteractiveCurrentIndexEnforce, 10, 40); + wait(1); mouseMove(listInteractiveCurrentIndexEnforce, 10, 30); + wait(1); mouseMove(listInteractiveCurrentIndexEnforce, 10, 20); + wait(1); mouseMove(listInteractiveCurrentIndexEnforce, 10, 10); compare(listInteractiveCurrentIndexEnforce.interactive, false); mouseRelease(listInteractiveCurrentIndexEnforce, 10, 10); diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 96fe97f372..4a0b8a8bdf 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -1461,6 +1461,7 @@ void tst_qquickflickable::flickWithTouch(QQuickWindow *window, QTouchDevice *tou for (int i = 1; i <= 8; ++i) { QTest::touchEvent(window, touchDevice).move(0, from + i*diff/8, window); QQuickTouchUtils::flush(window); + QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements } QTest::touchEvent(window, touchDevice).release(0, to, window); QQuickTouchUtils::flush(window); diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp index aa1474df91..89d48c4f09 100644 --- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp +++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp @@ -1047,17 +1047,17 @@ void tst_QQuickMouseArea::clickThrough() QVERIFY(QTest::qWaitForWindowExposed(window.data())); QVERIFY(window->rootObject() != 0); + // to avoid generating a double click. + const int doubleClickInterval = qApp->styleHints()->mouseDoubleClickInterval() + 10; + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QTRY_COMPARE(window->rootObject()->property("presses").toInt(), 0); QTRY_COMPARE(window->rootObject()->property("clicks").toInt(), 1); - // to avoid generating a double click. - int doubleClickInterval = qApp->styleHints()->mouseDoubleClickInterval() + 10; - QTest::qWait(doubleClickInterval); - - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QCOMPARE(window->rootObject()->property("doubleClicks").toInt(), 0); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::qWait(1000); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); @@ -1087,9 +1087,7 @@ void tst_QQuickMouseArea::clickThrough() QCOMPARE(window->rootObject()->property("presses").toInt(), 0); QCOMPARE(window->rootObject()->property("clicks").toInt(), 0); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::qWait(1000); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QTest::qWait(100); @@ -1108,15 +1106,13 @@ void tst_QQuickMouseArea::clickThrough() window->rootObject()->setProperty("letThrough", QVariant(true)); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QCOMPARE(window->rootObject()->property("presses").toInt(), 0); QTRY_COMPARE(window->rootObject()->property("clicks").toInt(), 1); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::qWait(1000); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QTest::qWait(100); @@ -1135,12 +1131,10 @@ void tst_QQuickMouseArea::clickThrough() window->rootObject()->setProperty("noPropagation", QVariant(true)); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::qWait(1000); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QTest::qWait(100); @@ -1161,7 +1155,7 @@ void tst_QQuickMouseArea::clickThrough() QVERIFY(QTest::qWaitForWindowExposed(window.data())); QVERIFY(window->rootObject() != 0); - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QCOMPARE(window->rootObject()->property("clicksEnabled").toInt(), 1); @@ -1169,8 +1163,7 @@ void tst_QQuickMouseArea::clickThrough() window->rootObject()->setProperty("disableLower", QVariant(true)); - QTest::qWait(doubleClickInterval); // to avoid generating a double click. - QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100)); + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(100,100), doubleClickInterval); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(100,100)); QCOMPARE(window->rootObject()->property("clicksEnabled").toInt(), 2); diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp index c3981c466f..1b32e6c4ab 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp +++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp @@ -596,18 +596,22 @@ void tst_QQuickMultiPointTouchArea::inFlickable() QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); @@ -783,18 +787,22 @@ void tst_QQuickMultiPointTouchArea::inFlickable2() QCOMPARE(point11->pressed(), true); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); p1 += QPoint(0,15); + QTest::qWait(1); QTest::touchEvent(window.data(), device).move(0, p1); QQuickTouchUtils::flush(window.data()); diff --git a/tests/auto/quick/qquickpathview/data/qtbug37815.qml b/tests/auto/quick/qquickpathview/data/qtbug37815.qml new file mode 100644 index 0000000000..3fd4daca63 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/qtbug37815.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Netris +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + width: 600 + height: 400 + PathView { + objectName: "pathView" + model: 10 + anchors.fill: parent + pathItemCount: 5 + cacheItemCount: 5 + highlightRangeMode: PathView.StrictlyEnforceRange + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + + path: Path { + startX: 0 + startY: 50 + PathLine { + x: 600 + y: 50 + } + } + + delegate: Component { + Text { + width: 50 + height: 50 + text: index + objectName: "delegate" + index + font.pixelSize: 24 + color: PathView.isCurrentItem ? "green" : "black" + } + } + } +} + diff --git a/tests/auto/quick/qquickpathview/data/qtbug53464.qml b/tests/auto/quick/qquickpathview/data/qtbug53464.qml new file mode 100644 index 0000000000..d30d404e68 --- /dev/null +++ b/tests/auto/quick/qquickpathview/data/qtbug53464.qml @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Netris +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + width: 600 + height: 400 + PathView { + objectName: "pathView" + model: 10 + anchors.fill: parent + pathItemCount: 5 + highlightRangeMode: PathView.StrictlyEnforceRange + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + currentIndex: 8 + + path: Path { + startX: 0 + startY: 50 + PathLine { + x: 600 + y: 50 + } + } + + delegate: Component { + Text { + width: 50 + height: 50 + text: index + objectName: "delegate" + index + font.pixelSize: 24 + color: PathView.isCurrentItem ? "green" : "black" + } + } + } +} + diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 6761313210..d013d190ec 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -135,7 +135,9 @@ private slots: void nestedinFlickable(); void flickableDelegate(); void jsArrayChange(); + void qtbug37815(); void qtbug42716(); + void qtbug53464(); void addCustomAttribute(); void movementDirection_data(); void movementDirection(); @@ -2330,6 +2332,31 @@ void tst_QQuickPathView::jsArrayChange() QCOMPARE(spy.count(), 1); } +void tst_QQuickPathView::qtbug37815() +{ + QScopedPointer<QQuickView> window(createView()); + + window->setSource(testFileUrl("qtbug37815.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + // cache items will be created async. Let's wait... + QTest::qWait(1000); + + QQuickPathView *pathView = findItem<QQuickPathView>(window->rootObject(), "pathView"); + QVERIFY(pathView != Q_NULLPTR); + + const int pathItemCount = pathView->pathItemCount(); + const int cacheItemCount = pathView->cacheItemCount(); + int totalCount = 0; + foreach (QQuickItem *item, pathView->childItems()) { + if (item->objectName().startsWith(QLatin1String("delegate"))) + ++totalCount; + } + QCOMPARE(pathItemCount + cacheItemCount, totalCount); +} + /* This bug was one where if you jump the list such that the sole missing item needed to be * added in the middle of the list, it would instead move an item somewhere else in the list * to the middle (messing it up very badly). @@ -2378,6 +2405,29 @@ void tst_QQuickPathView::qtbug42716() QVERIFY(!itemMiss); } +void tst_QQuickPathView::qtbug53464() +{ + QScopedPointer<QQuickView> window(createView()); + + window->setSource(testFileUrl("qtbug53464.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + + QQuickPathView *pathView = findItem<QQuickPathView>(window->rootObject(), "pathView"); + QVERIFY(pathView != Q_NULLPTR); + const int currentIndex = pathView->currentIndex(); + QCOMPARE(currentIndex, 8); + + const int pathItemCount = pathView->pathItemCount(); + int totalCount = 0; + foreach (QQuickItem *item, pathView->childItems()) { + if (item->objectName().startsWith(QLatin1String("delegate"))) + ++totalCount; + } + QCOMPARE(pathItemCount, totalCount); +} + void tst_QQuickPathView::addCustomAttribute() { const QScopedPointer<QQuickView> window(createView()); diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index 15d7ffd9d9..a2a23031e1 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -586,10 +586,13 @@ void tst_TouchMouse::buttonOnFlickable() QPoint p2 = p1 + QPoint(0, -10); QPoint p3 = p2 + QPoint(0, -10); QQuickTouchUtils::flush(window); + QTest::qWait(1); // because Flickable pays attention to velocity, we need some time between movements QTest::touchEvent(window, device).move(0, p1, window); QQuickTouchUtils::flush(window); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p2, window); QQuickTouchUtils::flush(window); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p3, window); QQuickTouchUtils::flush(window); @@ -671,10 +674,13 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable() QPoint p2 = p1 + QPoint(0, -10); QPoint p3 = p2 + QPoint(0, -10); QQuickTouchUtils::flush(window); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p1, window); QQuickTouchUtils::flush(window); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p2, window); QQuickTouchUtils::flush(window); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p3, window); QQuickTouchUtils::flush(window); QVERIFY(flickable->isMovingVertically()); @@ -866,15 +872,19 @@ void tst_TouchMouse::pinchOnFlickable() QQuickTouchUtils::flush(window); QCOMPARE(rect->position(), QPointF(200.0, 200.0)); p -= QPoint(10, 0); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); + QTest::qWait(1); QTest::touchEvent(window, device).move(0, p, window); QQuickTouchUtils::flush(window); QTest::touchEvent(window, device).release(0, p, window); @@ -1087,13 +1097,16 @@ void tst_TouchMouse::mouseOnFlickableOnPinch() QQuickTouchUtils::flush(window); QCOMPARE(rect->position(), QPointF(200.0, 200.0)); p -= QPoint(10, 0); + QTest::qWait(1); pinchSequence.move(0, p, window).commit(); QQuickTouchUtils::flush(window); p -= QPoint(10, 0); + QTest::qWait(1); pinchSequence.move(0, p, window).commit(); QQuickTouchUtils::flush(window); QGuiApplication::processEvents(); p -= QPoint(10, 0); + QTest::qWait(1); pinchSequence.move(0, p, window).commit(); QQuickTouchUtils::flush(window); diff --git a/tests/benchmarks/qml/creation/creation.pro b/tests/benchmarks/qml/creation/creation.pro index bb4d2841fe..42faf729a0 100644 --- a/tests/benchmarks/qml/creation/creation.pro +++ b/tests/benchmarks/qml/creation/creation.pro @@ -1,7 +1,7 @@ CONFIG += benchmark TEMPLATE = app TARGET = tst_creation -QT += core-private gui-private qml-private quick-private widgets testlib +QT += core-private gui-private qml-private quick-private testlib macx:CONFIG -= app_bundle SOURCES += tst_creation.cpp diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp index b47bc14a3e..e5ad04b92f 100644 --- a/tests/benchmarks/qml/creation/tst_creation.cpp +++ b/tests/benchmarks/qml/creation/tst_creation.cpp @@ -31,8 +31,6 @@ #include <QQmlComponent> #include <private/qqmlmetatype_p.h> #include <QDebug> -#include <QGraphicsScene> -#include <QGraphicsItem> #include <QQuickItem> #include <QQmlContext> #include <private/qobject_p.h> @@ -47,7 +45,6 @@ private slots: void qobject_cpp(); void qobject_qml(); void qobject_qmltype(); - void qobject_alloc(); void qobject_10flat_qml(); void qobject_10flat_cpp(); @@ -62,9 +59,6 @@ private slots: void itemtree_qml(); void itemtree_scene_cpp(); - void elements_data(); - void elements(); - void itemtests_qml_data(); void itemtests_qml(); @@ -204,35 +198,6 @@ void tst_creation::qobject_qmltype() } } -struct QObjectFakeData { - char data[sizeof(QObjectPrivate)]; -}; - -struct QObjectFake { - QObjectFake(); - virtual ~QObjectFake(); -private: - QObjectFakeData *d; -}; - -QObjectFake::QObjectFake() -{ - d = new QObjectFakeData; -} - -QObjectFake::~QObjectFake() -{ - delete d; -} - -void tst_creation::qobject_alloc() -{ - QBENCHMARK { - QObjectFake *obj = new QObjectFake; - delete obj; - } -} - struct QQmlGraphics_Derived : public QObject { void setParent_noEvent(QObject *parent) { @@ -327,28 +292,6 @@ void tst_creation::itemtree_scene_cpp() delete root; } -void tst_creation::elements_data() -{ - QTest::addColumn<QString>("type"); - - QList<QString> types = QQmlMetaType::qmlTypeNames(); - foreach (QString type, types) - QTest::newRow(type.toLatin1()) << type; -} - -void tst_creation::elements() -{ - QFETCH(QString, type); - QQmlType *t = QQmlMetaType::qmlType(type, 2, 0); - if (!t || !t->isCreatable()) - QSKIP("Non-creatable type"); - - QBENCHMARK { - QObject *obj = t->create(); - delete obj; - } -} - void tst_creation::itemtests_qml_data() { QTest::addColumn<QString>("filepath"); diff --git a/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp b/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp index 5513dcb9a7..d7c54703ad 100644 --- a/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp +++ b/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp @@ -36,9 +36,6 @@ // for the standard set of elements, properties and expressions which // are provided in the QtDeclarative library (QtQml and QtQuick). -#define AVERAGE_OVER_N 10 -#define IGNORE_N_OUTLIERS 2 - class ModuleApi : public QObject { Q_OBJECT @@ -214,123 +211,37 @@ void tst_librarymetrics_performance::compilation() } } - QList<qint64> nResults; - - // generate AVERAGE_OVER_N results - for (int i = 0; i < AVERAGE_OVER_N; ++i) { + QBENCHMARK { cleanState(&e); - { - QElapsedTimer et; - et.start(); - QQmlComponent c(e, this); - c.loadUrl(qmlfile); // just compile. - qint64 etime = et.nsecsElapsed(); - nResults.append(etime); - } - } - - // sort the list - qSort(nResults); - - // remove IGNORE_N_OUTLIERS*2 from ONLY the worst end (remove gc interference) - for (int i = 0; i < IGNORE_N_OUTLIERS; ++i) { - if (!nResults.isEmpty()) nResults.removeLast(); - if (!nResults.isEmpty()) nResults.removeLast(); + QQmlComponent c(e, this); + c.loadUrl(qmlfile); // just compile. } - - // now generate an average - qint64 totaltime = 0; - if (nResults.size() == 0) nResults.append(9999); - for (int i = 0; i < nResults.size(); ++i) - totaltime += nResults.at(i); - double average = ((double)totaltime) / nResults.count(); - - // and return it as the result - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); // twice to workaround bug in QTestLib } void tst_librarymetrics_performance::instantiation_cached() { QFETCH(QUrl, qmlfile); - cleanState(&e); - QList<qint64> nResults; - // generate AVERAGE_OVER_N results - for (int i = 0; i < AVERAGE_OVER_N; ++i) { - QElapsedTimer et; - et.start(); + QBENCHMARK { QQmlComponent c(e, this); c.loadUrl(qmlfile); // just compile. QObject *o = c.create(); - qint64 etime = et.nsecsElapsed(); - nResults.append(etime); delete o; } - - // sort the list - qSort(nResults); - - // remove IGNORE_N_OUTLIERS*2 from ONLY the worst end (remove gc interference) - for (int i = 0; i < IGNORE_N_OUTLIERS; ++i) { - if (!nResults.isEmpty()) nResults.removeLast(); - if (!nResults.isEmpty()) nResults.removeLast(); - } - - // now generate an average - qint64 totaltime = 0; - if (nResults.size() == 0) nResults.append(9999); - for (int i = 0; i < nResults.size(); ++i) - totaltime += nResults.at(i); - double average = ((double)totaltime) / nResults.count(); - - // and return it as the result - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); // twice to workaround bug in QTestLib } void tst_librarymetrics_performance::instantiation() { QFETCH(QUrl, qmlfile); - cleanState(&e); - QList<qint64> nResults; - - // generate AVERAGE_OVER_N results - for (int i = 0; i < AVERAGE_OVER_N; ++i) { + QBENCHMARK { cleanState(&e); - { - QElapsedTimer et; - et.start(); - QQmlComponent c(e, this); - c.loadUrl(qmlfile); // just compile. - QObject *o = c.create(); - qint64 etime = et.nsecsElapsed(); - nResults.append(etime); - delete o; - } - } - - // sort the list - qSort(nResults); - - // remove IGNORE_N_OUTLIERS*2 from ONLY the worst end (remove gc interference) - for (int i = 0; i < IGNORE_N_OUTLIERS; ++i) { - if (!nResults.isEmpty()) nResults.removeLast(); - if (!nResults.isEmpty()) nResults.removeLast(); + QQmlComponent c(e, this); + c.loadUrl(qmlfile); // just compile. + QObject *o = c.create(); + delete o; } - - // now generate an average - qint64 totaltime = 0; - if (nResults.size() == 0) nResults.append(9999); - for (int i = 0; i < nResults.size(); ++i) - totaltime += nResults.at(i); - double average = ((double)totaltime) / nResults.count(); - - // and return it as the result - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); // twice to workaround bug in QTestLib } void tst_librarymetrics_performance::positioners_data() @@ -351,43 +262,13 @@ void tst_librarymetrics_performance::positioners() { QFETCH(QUrl, qmlfile); - cleanState(&e); - QList<qint64> nResults; - - // generate AVERAGE_OVER_N results - for (int i = 0; i < AVERAGE_OVER_N; ++i) { + QBENCHMARK { cleanState(&e); - { - QElapsedTimer et; - et.start(); - QQmlComponent c(e, this); - c.loadUrl(qmlfile); // just compile. - QObject *o = c.create(); - qint64 etime = et.nsecsElapsed(); - nResults.append(etime); - delete o; - } - } - - // sort the list - qSort(nResults); - - // remove IGNORE_N_OUTLIERS*2 from ONLY the worst end (remove gc interference) - for (int i = 0; i < IGNORE_N_OUTLIERS; ++i) { - if (!nResults.isEmpty()) nResults.removeLast(); - if (!nResults.isEmpty()) nResults.removeLast(); + QQmlComponent c(e, this); + c.loadUrl(qmlfile); // just compile. + QObject *o = c.create(); + delete o; } - - // now generate an average - qint64 totaltime = 0; - if (nResults.size() == 0) nResults.append(9999); - for (int i = 0; i < nResults.size(); ++i) - totaltime += nResults.at(i); - double average = ((double)totaltime) / nResults.count(); - - // and return it as the result - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); - QTest::setBenchmarkResult(average, QTest::WalltimeNanoseconds); // twice to workaround bug in QTestLib } QTEST_MAIN(tst_librarymetrics_performance) diff --git a/tests/benchmarks/qml/qml.pro b/tests/benchmarks/qml/qml.pro index 5d48ec0067..2cf2dff413 100644 --- a/tests/benchmarks/qml/qml.pro +++ b/tests/benchmarks/qml/qml.pro @@ -7,13 +7,12 @@ SUBDIRS += \ holistic \ qqmlchangeset \ qqmlcomponent \ - qqmlimage \ qqmlmetaproperty \ librarymetrics_performance \ # script \ ### FIXME: doesn't build - js + js \ + creation qtHaveModule(opengl): SUBDIRS += painting qquickwindow -qtHaveModule(widgets): SUBDIRS += creation include(../trusted-benchmarks.pri) diff --git a/tests/benchmarks/qml/qqmlimage/image.png b/tests/benchmarks/qml/qqmlimage/image.png Binary files differdeleted file mode 100644 index 623d36233d..0000000000 --- a/tests/benchmarks/qml/qqmlimage/image.png +++ /dev/null diff --git a/tests/benchmarks/qml/qqmlimage/qqmlimage.pro b/tests/benchmarks/qml/qqmlimage/qqmlimage.pro deleted file mode 100644 index 421f232a4f..0000000000 --- a/tests/benchmarks/qml/qqmlimage/qqmlimage.pro +++ /dev/null @@ -1,11 +0,0 @@ -CONFIG += benchmark -TEMPLATE = app -TARGET = tst_qqmlimage -QT += qml quick-private testlib -macx:CONFIG -= app_bundle -CONFIG += release - -SOURCES += tst_qqmlimage.cpp - -DEFINES += SRCDIR=\\\"$$PWD\\\" - diff --git a/tests/benchmarks/qml/qqmlimage/tst_qqmlimage.cpp b/tests/benchmarks/qml/qqmlimage/tst_qqmlimage.cpp deleted file mode 100644 index 38fca802c5..0000000000 --- a/tests/benchmarks/qml/qqmlimage/tst_qqmlimage.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qtest.h> -#include <QQmlEngine> -#include <QQmlComponent> -#include <private/qquickimage_p.h> - -class tst_qmlgraphicsimage : public QObject -{ - Q_OBJECT -public: - tst_qmlgraphicsimage() {} - -private slots: - void qmlgraphicsimage(); - void qmlgraphicsimage_file(); - void qmlgraphicsimage_url(); - -private: - QQmlEngine engine; -}; - -void tst_qmlgraphicsimage::qmlgraphicsimage() -{ - int x = 0; - QUrl url(SRCDIR "/image.png"); - QBENCHMARK { - QUrl url2("http://localhost/image" + QString::number(x++) + ".png"); - QQuickImage *image = new QQuickImage; - QQmlEngine::setContextForObject(image, engine.rootContext()); - delete image; - } -} - -void tst_qmlgraphicsimage::qmlgraphicsimage_file() -{ - int x = 0; - QUrl url(SRCDIR "/image.png"); - //get rid of initialization effects - { - QQuickImage *image = new QQuickImage; - QQmlEngine::setContextForObject(image, engine.rootContext()); - image->setSource(url); - } - QBENCHMARK { - QUrl url2("http://localhost/image" + QString::number(x++) + ".png"); - QQuickImage *image = new QQuickImage; - QQmlEngine::setContextForObject(image, engine.rootContext()); - image->setSource(url); - delete image; - } -} - -void tst_qmlgraphicsimage::qmlgraphicsimage_url() -{ - int x = 0; - QUrl url(SRCDIR "/image.png"); - QBENCHMARK { - QUrl url2("http://localhost/image" + QString::number(x++) + ".png"); - QQuickImage *image = new QQuickImage; - QQmlEngine::setContextForObject(image, engine.rootContext()); - image->setSource(url2); - delete image; - } -} - -QTEST_MAIN(tst_qmlgraphicsimage) - -#include "tst_qqmlimage.moc" |