aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-02-11 11:08:11 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2014-02-11 12:00:31 +0100
commit7c9497a6d47a02d961baef3993ba4cf4267ec607 (patch)
tree335fae3e9e3a84d33310efca23f1d6993265805b /src
parent67ba88947f57ab2d1859bbeb96c6dcba020561b1 (diff)
parent6c840c70d61c3ae277b60a024a086215c743e5b3 (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')
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp2
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h4
-rw-r--r--src/qml/compiler/qv4regalloc.cpp34
-rw-r--r--src/qml/compiler/qv4ssa.cpp9
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc2
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4context.cpp2
-rw-r--r--src/qml/jsruntime/qv4context_p.h2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp15
-rw-r--r--src/qml/qml/qqmlengine.cpp4
-rw-r--r--src/qml/qml/qqmllocale.cpp9
-rw-r--r--src/qml/qml/qqmlvme.cpp6
-rw-r--r--src/quick/items/qquickflickable.cpp2
-rw-r--r--src/quick/items/qquickflipable.cpp2
-rw-r--r--src/quick/items/qquickitem.cpp2
-rw-r--r--src/quick/items/qquickitemview.cpp5
-rw-r--r--src/quick/items/qquicktext.cpp4
-rw-r--r--src/quick/items/qquicktranslate.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp67
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h5
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterial.h2
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp19
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h4
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp23
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h3
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp2
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp2
-rw-r--r--src/quick/util/qquickpropertychanges.cpp5
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 &current, 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}
*/