diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-02-11 11:08:11 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2014-02-11 12:00:31 +0100 |
commit | 7c9497a6d47a02d961baef3993ba4cf4267ec607 (patch) | |
tree | 335fae3e9e3a84d33310efca23f1d6993265805b /src | |
parent | 67ba88947f57ab2d1859bbeb96c6dcba020561b1 (diff) | |
parent | 6c840c70d61c3ae277b60a024a086215c743e5b3 (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
src/qml/compiler/qv4ssa.cpp
src/qml/jsruntime/qv4arrayobject.cpp
src/qml/jsruntime/qv4context.cpp
Change-Id: Ied5b23bec4dc14abe51127c507aed668f855c1e1
Diffstat (limited to 'src')
28 files changed, 162 insertions, 78 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp index a1145c2f10..c89b108309 100644 --- a/src/qml/compiler/qv4isel_masm.cpp +++ b/src/qml/compiler/qv4isel_masm.cpp @@ -122,7 +122,7 @@ static const Assembler::RegisterID calleeSavedRegisters[] = { #if CPU(X86) static const Assembler::RegisterID calleeSavedRegisters[] = { - // Not used: JSC::X86Registers::ebx, + JSC::X86Registers::ebx, // temporary register JSC::X86Registers::esi, // ContextRegister JSC::X86Registers::edi // LocalsRegister }; diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h index b1e981533b..76fe6c6391 100644 --- a/src/qml/compiler/qv4isel_masm_p.h +++ b/src/qml/compiler/qv4isel_masm_p.h @@ -981,6 +981,10 @@ public: prepareRelativeCall(function, this); loadArgumentOnStackOrRegister<0>(arg1); +#if OS(LINUX) && CPU(X86) && (defined(__PIC__) || defined(__PIE__)) + load32(Address(StackFrameRegister, -sizeof(void*)), JSC::X86Registers::ebx); // restore the GOT ptr +#endif + callAbsolute(functionName, function); if (stackSpaceNeeded) diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp index bc88d5849a..cc9ce4fc96 100644 --- a/src/qml/compiler/qv4regalloc.cpp +++ b/src/qml/compiler/qv4regalloc.cpp @@ -114,6 +114,13 @@ public: return false; } + bool isUsedAt(const Temp &t, int position) { + foreach (const Use &use, uses(t)) + if (use.pos == position) + return true; + return false; + } + int def(const Temp &t) const { Q_ASSERT(_defs[t].isValid()); return _defs[t].defStmt; @@ -746,17 +753,17 @@ private: os << "Intervals live at the start of L" << bb->index << ":" << endl; if (_liveAtStart[bb].isEmpty()) os << "\t(none)" << endl; - foreach (const LifeTimeInterval &i, _liveAtStart[bb]) { + foreach (const LifeTimeInterval *i, _liveAtStart[bb]) { os << "\t"; - i.dump(os); + i->dump(os); os << endl; } os << "Intervals live at the end of L" << bb->index << ":" << endl; if (_liveAtEnd[bb].isEmpty()) os << "\t(none)" << endl; - foreach (const LifeTimeInterval &i, _liveAtEnd[bb]) { + foreach (const LifeTimeInterval *i, _liveAtEnd[bb]) { os << "\t"; - i.dump(os); + i->dump(os); os << endl; } #endif @@ -1069,6 +1076,8 @@ RegisterAllocator::RegisterAllocator(const QVector<int> &normalRegisters, const : _normalRegisters(normalRegisters) , _fpRegisters(fpRegisters) { + Q_ASSERT(normalRegisters.size() >= 2); + Q_ASSERT(fpRegisters.size() >= 2); } RegisterAllocator::~RegisterAllocator() @@ -1416,9 +1425,20 @@ void RegisterAllocator::allocateBlockedReg(LifeTimeInterval ¤t, const int #endif // DEBUG_REGALLOC current.setReg(reg); _lastAssignedRegister.insert(current.temp(), reg); - Q_ASSERT(nextUseRangeForReg[reg]); - Q_ASSERT(!nextUseRangeForReg[reg]->isFixedInterval()); - split(*nextUseRangeForReg[reg], position); + LifeTimeInterval *nextUse = nextUseRangeForReg[reg]; + Q_ASSERT(nextUse); + Q_ASSERT(!nextUse->isFixedInterval()); + + if (_info->isUsedAt(nextUse->temp(), position)) { + Q_ASSERT(!_info->isUsedAt(current.temp(), position)); + // the register is used (as an incoming parameter) at the current position, so split + // the interval immediately after the (use at the) current position + split(*nextUse, position + 1); + } else { + // the register was used before the current position + split(*nextUse, position); + } + splitInactiveAtEndOfLifetimeHole(reg, needsFPReg, position); // make sure that current does not intersect with the fixed interval for reg diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 3ffaca5134..8f3e186cc7 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -3711,9 +3711,12 @@ void LifeTimeInterval::dump(QTextStream &out) const { } bool LifeTimeInterval::lessThan(const LifeTimeInterval &r1, const LifeTimeInterval &r2) { - if (r1._ranges.first().start == r2._ranges.first().start) - return r1._ranges.last().end < r2._ranges.last().end; - else + if (r1._ranges.first().start == r2._ranges.first().start) { + if (r1.isSplitFromInterval() == r2.isSplitFromInterval()) + return r1._ranges.last().end < r2._ranges.last().end; + else + return r1.isSplitFromInterval(); + } else return r1._ranges.first().start < r2._ranges.first().start; } diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc index f336d14b14..2a9c94d22e 100644 --- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc @@ -568,7 +568,7 @@ any items added to this list for an \l Item are automatically added to its list of \l {Item::children}{children}. Default properties can be useful for reassigning the children of an item. See -the \l{declarative/ui-components/tabwidget}{TabWidget example}, which uses a +the \l{declarative/customitems/tabwidget}{TabWidget example}, which uses a default property to automatically reassign children of the TabWidget as children of an inner ListView. diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 652c0f00ac..efe1dff19c 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -304,7 +304,7 @@ ReturnedValue ArrayPrototype::method_push(CallContext *ctx) if (!ctx->callData->argc) { ; - } else if (!instance->protoHasArray() && instance->arrayData->length() <= len) { + } else if (!instance->protoHasArray() && instance->arrayData->length() <= len && instance->arrayType() == ArrayData::Simple) { instance->arrayData->vtable()->putArray(instance.getPointer(), len, ctx->callData->args, ctx->callData->argc); len = instance->arrayData->length(); } else { diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 15fea72b25..cec42e87aa 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -71,7 +71,7 @@ CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData c->lookups = c->compilationUnit->runtimeLookups; } - c->locals = (Value *)(c + 1); + c->locals = (Value *)((quintptr(c + 1) + 7) & ~7); if (function->varCount) std::fill(c->locals, c->locals + function->varCount, Primitive::undefinedValue()); diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 5904d0b638..f9511d98e3 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -258,7 +258,7 @@ inline Scope::Scope(ExecutionContext *ctx) /* Function *f, int argc */ #define requiredMemoryForExecutionContect(f, argc) \ - sizeof(CallContext) + sizeof(Value) * (f->varCount + qMax((uint)argc, f->formalParameterCount)) + sizeof(CallData) + ((sizeof(CallContext) + 7) & ~7) + sizeof(Value) * (f->varCount + qMax((uint)argc, f->formalParameterCount)) + sizeof(CallData) } // namespace QV4 diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 9bc01d12cc..7f4ac22377 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -317,7 +317,6 @@ ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextD return QV4::Object::get(this, name, hasProperty); } - QQmlData::flushPendingBinding(m_object, result->coreIndex); QQmlData *ddata = QQmlData::get(m_object, false); if (revisionMode == QV4::QObjectWrapper::CheckRevision && result->hasRevision()) { @@ -338,6 +337,8 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx { QV4::Scope scope(ctx); + QQmlData::flushPendingBinding(object, property->coreIndex); + if (property->isFunction() && !property->isVarProperty()) { if (property->isVMEFunction()) { QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object); @@ -774,11 +775,13 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase } f->call(callData); - if (scope.hasException()) { - QQmlError error = QV4::ExecutionEngine::catchExceptionAsQmlError(ctx); - if (error.description().isEmpty()) - error.setDescription(QString(QLatin1String("Unknown exception occurred during evaluation of connected function: %1")).arg(f->name->toQString())); - QQmlEnginePrivate::get(v4->v8Engine->engine())->warning(error); + if (scope.hasException() && v4->v8Engine) { + if (QQmlEngine *qmlEngine = v4->v8Engine->engine()) { + QQmlError error = QV4::ExecutionEngine::catchExceptionAsQmlError(ctx); + if (error.description().isEmpty()) + error.setDescription(QString(QLatin1String("Unknown exception occurred during evaluation of connected function: %1")).arg(f->name->toQString())); + QQmlEnginePrivate::get(qmlEngine)->warning(error); + } } } break; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 8e61ba61cc..68d021b5cb 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -779,8 +779,8 @@ void QQmlData::flushPendingBindingImpl(int coreIndex) while (b && *b->m_mePtr && b->propertyIndex() != coreIndex) b = b->nextBinding(); - if (b) { - b->m_mePtr = 0; + if (b && b->propertyIndex() == coreIndex) { + b->clear(); b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding); } diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 0ea9785673..fc9e2fc42a 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -1066,9 +1066,12 @@ QV4::ReturnedValue QQmlLocale::method_localeCompare(QV4::CallContext *ctx) \list \li Locale.MetricSystem This value indicates metric units, such as meters, centimeters and millimeters. - \li Locale.ImperialSystem This value indicates imperial units, such as inches and - miles. There are several distinct imperial systems in the world; this - value stands for the official United States imperial units. + \li Locale.ImperialUSSystem This value indicates imperial units, such as + inches and miles as they are used in the United States. + \li Locale.ImperialUKSystem This value indicates imperial units, such as + inches and miles as they are used in the United Kingdom. + \li Locale.ImperialSystem Provided for compatibility. The same as + Locale.ImperialUSSystem. \endlist */ diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index 7d1e8cc8f0..54c70feecc 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -871,6 +871,12 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, CLEAN_PROPERTY(target, QDPP::bindingIndex(instr.property)); bind->addToObject(); + + if (!instr.property.isValueTypeVirtual()) { + QQmlData *data = QQmlData::get(target); + Q_ASSERT(data); + data->setPendingBindingBit(target, instr.property.coreIndex); + } } QML_END_INSTR(StoreBinding) diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index ec199a5a9b..789d1952c0 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -665,7 +665,7 @@ is finished. \dots 8 \snippet qml/flickableScrollbar.qml 1 - \sa {declarative/ui-components/scrollbar}{scrollbar example} + \sa {declarative/customitems/scrollbar}{scrollbar example} */ QQuickFlickable::QQuickFlickable(QQuickItem *parent) : QQuickItem(*(new QQuickFlickablePrivate), parent) diff --git a/src/quick/items/qquickflipable.cpp b/src/quick/items/qquickflipable.cpp index 15ebf776aa..1ea5e57656 100644 --- a/src/quick/items/qquickflipable.cpp +++ b/src/quick/items/qquickflipable.cpp @@ -127,7 +127,7 @@ public: state, and \l {Animation and Transitions in Qt Quick} for more information on how animations work within transitions. - \sa {declarative/ui-components/flipable}{Flipable example} + \sa {declarative/customitems/flipable}{Flipable example} */ QQuickFlipable::QQuickFlipable(QQuickItem *parent) : QQuickItem(*(new QQuickFlipablePrivate), parent) diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 2a507a27b1..3b63028a2e 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -1202,6 +1202,8 @@ QQuickKeysAttached::QQuickKeysAttached(QObject *parent) Q_D(QQuickKeysAttached); m_processPost = false; d->item = qmlobject_cast<QQuickItem*>(parent); + if (d->item != parent) + qWarning() << "Could not attach Keys property to: " << parent << " is not an Item"; } QQuickKeysAttached::~QQuickKeysAttached() diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index f5c0e3b8d2..10f134f7ae 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -66,6 +66,7 @@ FxViewItem::~FxViewItem() { delete transitionableItem; if (ownItem && item) { + trackGeometry(false); item->setParentItem(0); item->deleteLater(); item = 0; @@ -1415,7 +1416,7 @@ qreal QQuickItemView::originX() const if (d->layoutOrientation() == Qt::Horizontal && effectiveLayoutDirection() == Qt::RightToLeft && contentWidth() < width()) { - return d->lastPosition() - d->footerSize(); + return -d->lastPosition() - d->footerSize(); } return QQuickFlickable::originX(); } @@ -1426,7 +1427,7 @@ qreal QQuickItemView::originY() const if (d->layoutOrientation() == Qt::Vertical && d->verticalLayoutDirection == QQuickItemView::BottomToTop && contentHeight() < height()) { - return d->lastPosition() - d->footerSize(); + return -d->lastPosition() - d->footerSize(); } return QQuickFlickable::originY(); } diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index ae14a43de0..287173957f 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -2363,6 +2363,10 @@ void QQuickText::setLineHeightMode(LineHeightMode mode) minimumPointSize or minimumPixelSize property and maximum bound specified by either the \l font.pointSize or \l font.pixelSize properties. + \qml + Text { text: "Hello"; fontSizeMode: Text.Fit; minimumPixelSize: 10; font.pixelSize: 72 } + \endqml + If the text does not fit within the item bounds with the minimum font size the text will be elided as per the \l elide property. */ diff --git a/src/quick/items/qquicktranslate.cpp b/src/quick/items/qquicktranslate.cpp index 5c61fb33f8..14f8c204f3 100644 --- a/src/quick/items/qquicktranslate.cpp +++ b/src/quick/items/qquicktranslate.cpp @@ -336,7 +336,7 @@ public: \image axisrotation.png - \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {Qt Quick Demo - Clocks} + \sa {declarative/customitems/dialcontrol}{Dial Control example}, {Qt Quick Demo - Clocks} */ QQuickRotation::QQuickRotation(QObject *parent) : QQuickTransform(*new QQuickRotationPrivate, parent) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 9de7bb8667..8dfa0d2c2c 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Jolla Ltd, author: <gunnar.sletta@jollamobile.com> ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -317,7 +318,7 @@ void Updater::updateStates(QSGNode *n) void Updater::visitNode(Node *n) { - if (m_added == 0 && n->dirtyState == 0 && m_force_update == 0 && m_transformChange == 0) + if (m_added == 0 && n->dirtyState == 0 && m_force_update == 0 && m_transformChange == 0 && m_opacityChange == 0) return; int count = m_added; @@ -394,13 +395,10 @@ void Updater::visitOpacityNode(Node *n) if (was != is) { renderer->m_rebuild = Renderer::FullRebuild; n->isOpaque = is; - } else if (!is) { - renderer->invalidateAlphaBatchesForRoot(m_roots.last()); - renderer->m_rebuild |= Renderer::BuildBatches; } - ++m_force_update; + ++m_opacityChange; SHADOWNODE_TRAVERSE(n) visitNode(*child); - --m_force_update; + --m_opacityChange; } else { if (m_added > 0) n->isOpaque = on->opacity() > OPAQUE_LIMIT; @@ -491,9 +489,16 @@ void Updater::visitGeometryNode(Node *n) } else { renderer->m_rebuild |= Renderer::FullRebuild; } - } else if (m_transformChange) { - Element *e = n->element(); - e->translateOnlyToRoot = QMatrix4x4_Accessor::isTranslate(*gn->matrix()); + } else { + if (m_transformChange) { + Element *e = n->element(); + e->translateOnlyToRoot = QMatrix4x4_Accessor::isTranslate(*gn->matrix()); + } + if (m_opacityChange) { + Element *e = n->element(); + if (e->batch) + renderer->invalidateBatchAndOverlappingRenderOrders(e->batch); + } } SHADOWNODE_TRAVERSE(n) visitNode(*child); @@ -971,12 +976,7 @@ void Renderer::nodeWasTransformed(Node *node, int *vertexCount) e->boundsComputed = false; if (e->batch) { if (!e->batch->isOpaque) { - if (e->root) { - m_taggedRoots << e->root; - m_rebuild |= BuildRenderListsForTaggedRoots; - } else { - m_rebuild |= FullRebuild; - } + invalidateBatchAndOverlappingRenderOrders(e->batch); } else if (e->batch->merged) { e->batch->needsUpload = true; } @@ -1176,15 +1176,8 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) e->boundsComputed = false; Batch *b = e->batch; if (b) { - if (!e->batch->geometryWasChanged(gn)) { - m_rebuild |= Renderer::FullRebuild; - } else if (!b->isOpaque) { - if (e->root) { - m_taggedRoots << e->root; - m_rebuild |= BuildRenderListsForTaggedRoots; - } else { - m_rebuild |= FullRebuild; - } + if (!e->batch->geometryWasChanged(gn) || !e->batch->isOpaque) { + invalidateBatchAndOverlappingRenderOrders(e->batch); } else { b->needsUpload = true; } @@ -1197,7 +1190,7 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) if (e) { if (e->batch) { if (!e->batch->isMaterialCompatible(e)) - m_rebuild = Renderer::FullRebuild; + invalidateBatchAndOverlappingRenderOrders(e->batch); } else { m_rebuild |= Renderer::BuildBatches; } @@ -1427,13 +1420,26 @@ void Renderer::buildRenderListsFromScratch() buildRenderLists(rootNode()); } -void Renderer::invalidateAlphaBatchesForRoot(Node *root) +void Renderer::invalidateBatchAndOverlappingRenderOrders(Batch *batch) { + Q_ASSERT(batch); + Q_ASSERT(batch->first); + + int first = batch->first->order; + int last = batch->lastOrderInBatch; + batch->invalidate(); + for (int i=0; i<m_alphaBatches.size(); ++i) { Batch *b = m_alphaBatches.at(i); - if (b->root == root || root == 0) - b->invalidate(); + if (b->first) { + int bf = b->first->order; + int bl = b->lastOrderInBatch; + if (bl > first && bf < last) + b->invalidate(); + } } + + m_rebuild |= BuildBatches; } /* Clean up batches by making it a consecutive list of "valid" @@ -1493,6 +1499,8 @@ void Renderer::prepareOpaqueBatches() next = ej; } } + + batch->lastOrderInBatch = next->order; } } @@ -1595,6 +1603,8 @@ void Renderer::prepareAlphaBatches() overlapBounds |= ej->bounds; } } + + batch->lastOrderInBatch = next->order; } @@ -2329,7 +2339,6 @@ void Renderer::render() type += " batches"; } - qDebug() << "Renderer::render()" << this << type; } diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index d22ab4069e..c38c483df4 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -264,6 +264,8 @@ struct Batch int vertexCount; int indexCount; + int lastOrderInBatch; + uint isOpaque : 1; uint needsUpload : 1; uint merged : 1; @@ -351,6 +353,7 @@ private: int m_added; int m_transformChange; + int m_opacityChange; QMatrix4x4 m_identityMatrix; }; @@ -431,7 +434,7 @@ private: void prepareOpaqueBatches(); bool checkOverlap(int first, int last, const Rect &bounds); void prepareAlphaBatches(); - void invalidateAlphaBatchesForRoot(Node *root); + void invalidateBatchAndOverlappingRenderOrders(Batch *batch); void uploadBatch(Batch *b); void uploadMergedElement(Element *e, int vaOffset, char **vertexData, char **zData, char **indexData, quint16 *iBase, int *indexCount); diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.h b/src/quick/scenegraph/coreapi/qsgmaterial.h index bfe570ca02..98f4d8aecf 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.h +++ b/src/quick/scenegraph/coreapi/qsgmaterial.h @@ -103,7 +103,7 @@ protected: Q_DECLARE_PRIVATE(QSGMaterialShader) QSGMaterialShader(QSGMaterialShaderPrivate &dd); - friend class QSGContext; + friend class QSGRenderContext; friend class QSGBatchRenderer::ShaderManager; void setShaderSourceFile(QOpenGLShader::ShaderType type, const QString &sourceFile); diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 202ae91ac3..dd00f75fae 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -174,6 +174,11 @@ QSGContext::~QSGContext() { } +QSGRenderContext *QSGContext::createRenderContext() +{ + return new QSGRenderContext(this); +} + /*! * This function is used by the Qt WebEngine to set up context sharing * across multiple windows. Do not use it for any other purpose. @@ -423,6 +428,20 @@ void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine) } /*! + compile/initialize are protected member functions of QSGMaterialShader. + We expose them here for custom renderers. + */ +void QSGRenderContext::compileShader(QSGMaterialShader *shader) +{ + shader->compile(); +} + +void QSGRenderContext::initializeShader(QSGMaterialShader *shader) +{ + shader->initialize(); +} + +/*! Initializes the scene graph render context with the GL context \a context. This also emits the ready() signal so that the QML graph can start building scene graph nodes. */ diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 883287e35d..3b58cecd6a 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -112,6 +112,9 @@ public: bool hasBrokenIndexBufferObjects() const { return m_brokenIBOs; } + void compileShader(QSGMaterialShader *shader); + void initializeShader(QSGMaterialShader *shader); + Q_SIGNALS: void initialized(); void invalidated(); @@ -155,6 +158,7 @@ public: virtual void renderContextInitialized(QSGRenderContext *renderContext); virtual void renderContextInvalidated(QSGRenderContext *renderContext); + virtual QSGRenderContext *createRenderContext(); virtual QSGRectangleNode *createRectangleNode(); virtual QSGImageNode *createImageNode(); diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 5559745621..7b6e6d55ee 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -45,6 +45,7 @@ #include <QtCore/QCoreApplication> #include <QtCore/QTime> +#include <QtCore/QScopedPointer> #include <QtCore/private/qabstractanimation_p.h> #include <QtGui/QOpenGLContext> @@ -76,7 +77,7 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_ DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP); DEFINE_BOOL_CONFIG_OPTION(qmlForceThreadedRenderer, QML_FORCE_THREADED_RENDERER); // Might trigger graphics driver threading bugs, use at own risk -QSGRenderLoop *QSGRenderLoop::s_instance = 0; +Q_GLOBAL_STATIC(QScopedPointer<QSGRenderLoop>, s_renderLoopInstance); QSGRenderLoop::~QSGRenderLoop() { @@ -142,8 +143,8 @@ bool QSGRenderLoop::useConsistentTiming() QSGRenderLoop *QSGRenderLoop::instance() { - if (!s_instance) { - s_instance = QSGContext::createWindowManager(); + if (s_renderLoopInstance->isNull()) { + s_renderLoopInstance->reset(QSGContext::createWindowManager()); bool info = qEnvironmentVariableIsSet("QSG_INFO"); @@ -153,7 +154,7 @@ QSGRenderLoop *QSGRenderLoop::instance() qDebug() << "QSG: using fixed animation steps"; } - if (!s_instance) { + if (s_renderLoopInstance->isNull()) { enum RenderLoopType { BasicRenderLoop, @@ -185,26 +186,26 @@ QSGRenderLoop *QSGRenderLoop::instance() switch (loopType) { case ThreadedRenderLoop: if (info) qDebug() << "QSG: threaded render loop"; - s_instance = new QSGThreadedRenderLoop(); + s_renderLoopInstance->reset(new QSGThreadedRenderLoop()); break; case WindowsRenderLoop: if (info) qDebug() << "QSG: windows render loop"; - s_instance = new QSGWindowsRenderLoop(); + s_renderLoopInstance->reset(new QSGWindowsRenderLoop()); break; default: if (info) qDebug() << "QSG: basic render loop"; - s_instance = new QSGGuiThreadRenderLoop(); + s_renderLoopInstance->reset(new QSGGuiThreadRenderLoop()); break; } } } - return s_instance; + return s_renderLoopInstance->data(); } void QSGRenderLoop::setInstance(QSGRenderLoop *instance) { - Q_ASSERT(!s_instance); - s_instance = instance; + Q_ASSERT(!s_renderLoopInstance); + s_renderLoopInstance->reset(instance); } QSGGuiThreadRenderLoop::QSGGuiThreadRenderLoop() @@ -212,7 +213,7 @@ QSGGuiThreadRenderLoop::QSGGuiThreadRenderLoop() , eventPending(false) { sg = QSGContext::createDefaultContext(); - rc = new QSGRenderContext(sg); + rc = sg->createRenderContext(); } QSGGuiThreadRenderLoop::~QSGGuiThreadRenderLoop() diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h index 72bad16c63..46edd77eda 100644 --- a/src/quick/scenegraph/qsgrenderloop_p.h +++ b/src/quick/scenegraph/qsgrenderloop_p.h @@ -88,9 +88,6 @@ public: Q_SIGNALS: void timeToIncubate(); - -private: - static QSGRenderLoop *s_instance; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index bc08b70557..7cc4293f6c 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -706,7 +706,7 @@ QSGThreadedRenderLoop::QSGThreadedRenderLoop() QSGRenderContext *QSGThreadedRenderLoop::createRenderContext(QSGContext *sg) const { - return new QSGRenderContext(sg); + return sg->createRenderContext(); } void QSGThreadedRenderLoop::maybePostPolishRequest(Window *w) diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index c3656eac7a..63e3e958f6 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -85,7 +85,7 @@ QSGWindowsRenderLoop::QSGWindowsRenderLoop() qsg_debug_timer.start(); #endif - m_rc = new QSGRenderContext(m_sg); + m_rc = m_sg->createRenderContext(); m_animationDriver = m_sg->createAnimationDriver(m_sg); m_animationDriver->install(); diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 55ac85e64d..7bb318fd79 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -127,6 +127,11 @@ QT_BEGIN_NAMESPACE See the PropertyAction documentation for more details. + \note The \l{Item::}{visible} and \l{Item::}{enabled} properties of \l Item do not behave + exactly the same as other properties in PropertyChanges. Since these properties can be + changed implicitly through their parent's state, they should be set explicitly in all PropertyChanges. + An item will still not be enabled/visible if one of its parents is not enabled or visible. + \sa {declarative/animation/states}{states example}, {Qt Quick States}{Qt Quick States}, {Qt QML} */ |