Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts: src/qml/compiler/qv4ssa.cpp src/qml/qml/v8/qqmlbuiltinfunctions.cpp src/quick/util/qquickprofiler_p.h Change-Id: I11a89c2a166115d6697adfba09928805643e709e
This commit is contained in:
commit
cc1c3d0e2b
|
@ -447,9 +447,9 @@ void QQuickFolderListModel::setFolder(const QUrl &folder)
|
|||
/*!
|
||||
\qmlproperty url FolderListModel::rootFolder
|
||||
|
||||
When the rootFolder is set, then this folder will
|
||||
be threated as the root in the file system, so that
|
||||
you can only travers sub folders from this rootFolder.
|
||||
When this property is set, the given folder will
|
||||
be treated as the root in the file system, so that
|
||||
you can only traverse subfolders within it.
|
||||
*/
|
||||
QUrl QQuickFolderListModel::rootFolder() const
|
||||
{
|
||||
|
|
|
@ -1857,11 +1857,6 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return worklistSize == 0;
|
||||
}
|
||||
|
||||
unsigned size() const
|
||||
{
|
||||
return worklistSize;
|
||||
|
@ -1869,7 +1864,7 @@ public:
|
|||
|
||||
Stmt *takeNext(Stmt *last)
|
||||
{
|
||||
if (isEmpty())
|
||||
if (worklistSize == 0)
|
||||
return 0;
|
||||
|
||||
const int startAt = last ? last->id() + 1 : 0;
|
||||
|
@ -1885,6 +1880,10 @@ public:
|
|||
--worklistSize;
|
||||
Stmt *s = stmts.at(pos);
|
||||
Q_ASSERT(s);
|
||||
|
||||
if (removed.at(s->id()))
|
||||
return takeNext(s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -3857,9 +3856,7 @@ void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df)
|
|||
ExprReplacer replaceUses(defUses, function);
|
||||
|
||||
Stmt *s = 0;
|
||||
while (!W.isEmpty()) {
|
||||
s = W.takeNext(s);
|
||||
Q_ASSERT(s);
|
||||
while ((s = W.takeNext(s))) {
|
||||
|
||||
if (Phi *phi = s->asPhi()) {
|
||||
// dead code elimination:
|
||||
|
|
|
@ -78,13 +78,13 @@ Rectangle {
|
|||
|
||||
\code
|
||||
// my_button_impl.js
|
||||
property var clickCount = 0; // this state is separate for each instance of MyButton
|
||||
function onClicked(btn) {
|
||||
var clickCount = 0; // this state is separate for each instance of MyButton
|
||||
function onClicked(button) {
|
||||
clickCount += 1;
|
||||
if ((clickCount % 5) == 0) {
|
||||
obj.color = Qt.rgba(1,0,0,1);
|
||||
button.color = Qt.rgba(1,0,0,1);
|
||||
} else {
|
||||
obj.color = Qt.rgba(0,1,0,1);
|
||||
button.color = Qt.rgba(0,1,0,1);
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
|
|
@ -1877,7 +1877,7 @@ bool InstructionSelection::visitCJumpStrictUndefined(IR::Binop *binop,
|
|||
|
||||
Assembler::RelationalCondition cond = binop->op == IR::OpStrictEqual ? Assembler::Equal
|
||||
: Assembler::NotEqual;
|
||||
const Assembler::RegisterID tagReg = Assembler::ScratchRegister;
|
||||
const Assembler::RegisterID tagReg = Assembler::ReturnValueRegister;
|
||||
#ifdef QV4_USE_64_BIT_VALUE_ENCODING
|
||||
Assembler::Pointer addr = _as->loadAddress(Assembler::ScratchRegister, varSrc);
|
||||
_as->load64(addr, tagReg);
|
||||
|
@ -1976,7 +1976,7 @@ bool InstructionSelection::visitCJumpNullUndefined(IR::Type nullOrUndef, IR::Bin
|
|||
|
||||
Assembler::Pointer tagAddr = _as->loadAddress(Assembler::ScratchRegister, varSrc);
|
||||
tagAddr.offset += 4;
|
||||
const Assembler::RegisterID tagReg = Assembler::ScratchRegister;
|
||||
const Assembler::RegisterID tagReg = Assembler::ReturnValueRegister;
|
||||
_as->load32(tagAddr, tagReg);
|
||||
|
||||
if (binop->op == IR::OpNotEqual)
|
||||
|
|
|
@ -122,6 +122,7 @@ private:
|
|||
_allocatedBlocks *= 2;
|
||||
|
||||
_blocks = (char **) realloc(_blocks, sizeof(char *) * _allocatedBlocks);
|
||||
Q_CHECK_PTR(_blocks);
|
||||
|
||||
for (int index = _blockCount; index < _allocatedBlocks; ++index)
|
||||
_blocks[index] = 0;
|
||||
|
@ -129,8 +130,10 @@ private:
|
|||
|
||||
char *&block = _blocks[_blockCount];
|
||||
|
||||
if (! block)
|
||||
if (! block) {
|
||||
block = (char *) malloc(BLOCK_SIZE);
|
||||
Q_CHECK_PTR(block);
|
||||
}
|
||||
|
||||
_ptr = block;
|
||||
_end = _ptr + BLOCK_SIZE;
|
||||
|
|
|
@ -71,6 +71,12 @@ namespace {
|
|||
};
|
||||
}
|
||||
|
||||
void QQmlNotifier::notify(QQmlData *ddata, int notifierIndex)
|
||||
{
|
||||
if (QQmlNotifierEndpoint *ep = ddata->notify(notifierIndex))
|
||||
emitNotify(ep, Q_NULLPTR);
|
||||
}
|
||||
|
||||
void QQmlNotifier::emitNotify(QQmlNotifierEndpoint *endpoint, void **a)
|
||||
{
|
||||
QVarLengthArray<NotifyListTraversalData> stack;
|
||||
|
|
|
@ -65,6 +65,8 @@ public:
|
|||
inline ~QQmlNotifier();
|
||||
inline void notify();
|
||||
|
||||
static void notify(QQmlData *ddata, int notifierIndex);
|
||||
|
||||
private:
|
||||
friend class QQmlData;
|
||||
friend class QQmlNotifierEndpoint;
|
||||
|
|
|
@ -360,6 +360,7 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha
|
|||
|
||||
// These four types are the most common used by the value type wrappers
|
||||
VALUE_TYPE_LOAD(QMetaType::QReal, qreal, qreal);
|
||||
VALUE_TYPE_LOAD(QMetaType::Int || result->isEnum(), int, int);
|
||||
VALUE_TYPE_LOAD(QMetaType::Int, int, int);
|
||||
VALUE_TYPE_LOAD(QMetaType::QString, QString, v4->newString);
|
||||
VALUE_TYPE_LOAD(QMetaType::Bool, bool, bool);
|
||||
|
|
|
@ -999,7 +999,7 @@ ReturnedValue QtObject::method_quit(CallContext *ctx)
|
|||
/*!
|
||||
\qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath)
|
||||
|
||||
Returns a new object created from the given \a string of QML which will have the specified \a parent,
|
||||
Returns a new object created from the given \a qml string which will have the specified \a parent,
|
||||
or \c null if there was an error in creating the object.
|
||||
|
||||
If \a filepath is specified, it will be used for error reporting for the created object.
|
||||
|
|
|
@ -46,10 +46,12 @@
|
|||
|
||||
#include <private/qqmlcustomparser_p.h>
|
||||
#include <private/qqmlengine_p.h>
|
||||
#include <private/qqmlnotifier_p.h>
|
||||
|
||||
#include <private/qv4object_p.h>
|
||||
#include <private/qv4dateobject_p.h>
|
||||
#include <private/qv4objectiterator_p.h>
|
||||
#include <private/qv4alloca_p.h>
|
||||
|
||||
#include <qqmlcontext.h>
|
||||
#include <qqmlinfo.h>
|
||||
|
@ -58,6 +60,7 @@
|
|||
#include <QtCore/qstack.h>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QtCore/qdatetime.h>
|
||||
#include <QScopedValueRollback>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -1263,9 +1266,14 @@ ModelNodeMetaObject *ModelNodeMetaObject::get(QObject *obj)
|
|||
|
||||
void ModelNodeMetaObject::updateValues()
|
||||
{
|
||||
if (!m_initialized)
|
||||
const int roleCount = m_model->m_listModel->roleCount();
|
||||
if (!m_initialized) {
|
||||
int *changedRoles = reinterpret_cast<int *>(alloca(roleCount * sizeof(int)));
|
||||
for (int i = 0; i < roleCount; ++i)
|
||||
changedRoles[i] = i;
|
||||
emitDirectNotifies(changedRoles, roleCount);
|
||||
return;
|
||||
int roleCount = m_model->m_listModel->roleCount();
|
||||
}
|
||||
for (int i=0 ; i < roleCount ; ++i) {
|
||||
const ListLayout::Role &role = m_model->m_listModel->getExistingRole(i);
|
||||
QByteArray name = role.name.toUtf8();
|
||||
|
@ -1276,8 +1284,10 @@ void ModelNodeMetaObject::updateValues()
|
|||
|
||||
void ModelNodeMetaObject::updateValues(const QVector<int> &roles)
|
||||
{
|
||||
if (!m_initialized)
|
||||
if (!m_initialized) {
|
||||
emitDirectNotifies(roles.constData(), roles.count());
|
||||
return;
|
||||
}
|
||||
int roleCount = roles.count();
|
||||
for (int i=0 ; i < roleCount ; ++i) {
|
||||
int roleIndex = roles.at(i);
|
||||
|
@ -1307,6 +1317,22 @@ void ModelNodeMetaObject::propertyWritten(int index)
|
|||
}
|
||||
}
|
||||
|
||||
// Does the emission of the notifiers when we haven't created the meta-object yet
|
||||
void ModelNodeMetaObject::emitDirectNotifies(const int *changedRoles, int roleCount)
|
||||
{
|
||||
Q_ASSERT(!m_initialized);
|
||||
QQmlData *ddata = QQmlData::get(object(), /*create*/false);
|
||||
if (!ddata)
|
||||
return;
|
||||
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine(m_model));
|
||||
if (!ep)
|
||||
return;
|
||||
for (int i = 0; i < roleCount; ++i) {
|
||||
const int changedRole = changedRoles[i];
|
||||
QQmlNotifier::notify(ddata, changedRole);
|
||||
}
|
||||
}
|
||||
|
||||
namespace QV4 {
|
||||
|
||||
void ModelObject::put(Managed *m, String *name, const Value &value)
|
||||
|
@ -1336,6 +1362,18 @@ ReturnedValue ModelObject::get(const Managed *m, String *name, bool *hasProperty
|
|||
return QObjectWrapper::get(m, name, hasProperty);
|
||||
if (hasProperty)
|
||||
*hasProperty = true;
|
||||
|
||||
if (QQmlEngine *qmlEngine = that->engine()->qmlEngine()) {
|
||||
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine);
|
||||
if (ep && ep->propertyCapture) {
|
||||
QObjectPrivate *op = QObjectPrivate::get(that->object());
|
||||
// Temporarily hide the dynamic meta-object, to prevent it from being created when the capture
|
||||
// triggers a QObject::connectNotify() by calling obj->metaObject().
|
||||
QScopedValueRollback<QDynamicMetaObjectData*> metaObjectBlocker(op->metaObject, 0);
|
||||
ep->propertyCapture->captureProperty(that->object(), -1, role->index);
|
||||
}
|
||||
}
|
||||
|
||||
const int elementIndex = that->d()->m_elementIndex;
|
||||
QVariant value = that->d()->m_model->data(elementIndex, role->index);
|
||||
return that->engine()->fromVariant(value);
|
||||
|
|
|
@ -153,6 +153,8 @@ private:
|
|||
setValue(name, val);
|
||||
}
|
||||
|
||||
void emitDirectNotifies(const int *changedRoles, int roleCount);
|
||||
|
||||
void initialize();
|
||||
bool m_initialized;
|
||||
};
|
||||
|
|
|
@ -99,10 +99,12 @@ QSGGlyphNode *QQuickTextNode::addGlyphs(const QPointF &position, const QGlyphRun
|
|||
bool preferNativeGlyphNode = m_useNativeRenderer;
|
||||
if (!preferNativeGlyphNode) {
|
||||
QRawFontPrivate *fontPriv = QRawFontPrivate::get(font);
|
||||
if (fontPriv->fontEngine->hasUnreliableGlyphOutline())
|
||||
if (fontPriv->fontEngine->hasUnreliableGlyphOutline()) {
|
||||
preferNativeGlyphNode = true;
|
||||
else
|
||||
preferNativeGlyphNode = !QFontDatabase().isSmoothlyScalable(font.familyName(), font.styleName());
|
||||
} else {
|
||||
QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
|
||||
preferNativeGlyphNode = !fe->isSmoothlyScalable;
|
||||
}
|
||||
}
|
||||
|
||||
QSGGlyphNode *node = sg->sceneGraphContext()->createGlyphNode(sg, preferNativeGlyphNode);
|
||||
|
|
|
@ -170,7 +170,8 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material)
|
|||
|
||||
qCDebug(QSG_LOG_TIME_COMPILATION, "shader compiled in %dms", (int) qsg_renderer_timer.elapsed());
|
||||
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphContextFrame);
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphContextFrame,
|
||||
QQuickProfiler::SceneGraphContextMaterialCompile);
|
||||
|
||||
rewrittenShaders[type] = shader;
|
||||
return shader;
|
||||
|
@ -201,7 +202,8 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
|
|||
|
||||
qCDebug(QSG_LOG_TIME_COMPILATION, "shader compiled in %dms (no rewrite)", (int) qsg_renderer_timer.elapsed());
|
||||
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphContextFrame);
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphContextFrame,
|
||||
QQuickProfiler::SceneGraphContextMaterialCompile);
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
|
|
@ -205,7 +205,8 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
|
|||
bindable.bind();
|
||||
if (profileFrames)
|
||||
bindTime = frameTimer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
|
||||
QQuickProfiler::SceneGraphRendererBinding);
|
||||
|
||||
// Sanity check that attribute registers are disabled
|
||||
if (qsg_sanity_check) {
|
||||
|
@ -223,7 +224,8 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
|
|||
render();
|
||||
if (profileFrames)
|
||||
renderTime = frameTimer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRendererFrame);
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRendererFrame,
|
||||
QQuickProfiler::SceneGraphRendererRender);
|
||||
|
||||
m_is_rendering = false;
|
||||
m_changed_emitted = false;
|
||||
|
@ -287,13 +289,15 @@ void QSGRenderer::preprocess()
|
|||
bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled();
|
||||
if (profileFrames)
|
||||
preprocessTime = frameTimer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
|
||||
QQuickProfiler::SceneGraphRendererPreprocess);
|
||||
|
||||
nodeUpdater()->updateStates(root);
|
||||
|
||||
if (profileFrames)
|
||||
updatePassTime = frameTimer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
|
||||
QQuickProfiler::SceneGraphRendererUpdate);
|
||||
}
|
||||
|
||||
void QSGRenderer::addNodesToPreprocess(QSGNode *node)
|
||||
|
|
|
@ -185,7 +185,8 @@ void QSGDistanceFieldGlyphCache::update()
|
|||
int count = m_pendingGlyphs.size();
|
||||
if (profileFrames)
|
||||
renderTime = qsg_render_timer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphAdaptationLayerFrame);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
|
||||
QQuickProfiler::SceneGraphAdaptationLayerGlyphRender);
|
||||
|
||||
m_pendingGlyphs.reset();
|
||||
|
||||
|
@ -206,6 +207,7 @@ void QSGDistanceFieldGlyphCache::update()
|
|||
int((now - (renderTime / 1000000))));
|
||||
}
|
||||
Q_QUICK_SG_PROFILE_END_WITH_PAYLOAD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
|
||||
QQuickProfiler::SceneGraphAdaptationLayerGlyphStore,
|
||||
(qint64)count);
|
||||
}
|
||||
|
||||
|
|
|
@ -384,7 +384,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
|
|||
if (profileFrames)
|
||||
polishTime = renderTimer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
|
||||
QQuickProfiler::SceneGraphRenderLoopFrame);
|
||||
QQuickProfiler::SceneGraphRenderLoopFrame,
|
||||
QQuickProfiler::SceneGraphPolishPolish);
|
||||
|
||||
emit window->afterAnimating();
|
||||
|
||||
|
@ -392,13 +393,15 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
|
|||
|
||||
if (profileFrames)
|
||||
syncTime = renderTimer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
|
||||
QQuickProfiler::SceneGraphRenderLoopSync);
|
||||
|
||||
cd->renderSceneGraph(window->size());
|
||||
|
||||
if (profileFrames)
|
||||
renderTime = renderTimer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
|
||||
QQuickProfiler::SceneGraphRenderLoopRender);
|
||||
|
||||
if (data.grabOnly) {
|
||||
bool alpha = window->format().alphaBufferSize() > 0 && window->color().alpha() != 255;
|
||||
|
@ -415,7 +418,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
|
|||
qint64 swapTime = 0;
|
||||
if (profileFrames)
|
||||
swapTime = renderTimer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame);
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
|
||||
QQuickProfiler::SceneGraphRenderLoopSwap);
|
||||
|
||||
if (QSG_LOG_TIME_RENDERLOOP().isDebugEnabled()) {
|
||||
static QTime lastFrameTime = QTime::currentTime();
|
||||
|
|
|
@ -597,7 +597,8 @@ void QSGRenderThread::syncAndRender()
|
|||
if (profileFrames)
|
||||
syncTime = threadTimer.nsecsElapsed();
|
||||
#endif
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
|
||||
QQuickProfiler::SceneGraphRenderLoopSync);
|
||||
|
||||
if (!syncResultedInChanges && !repaintRequested && sgrc->isValid()) {
|
||||
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- no changes, render aborted";
|
||||
|
@ -629,12 +630,14 @@ void QSGRenderThread::syncAndRender()
|
|||
d->renderSceneGraph(windowSize);
|
||||
if (profileFrames)
|
||||
renderTime = threadTimer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
|
||||
QQuickProfiler::SceneGraphRenderLoopRender);
|
||||
if (!d->customRenderStage || !d->customRenderStage->swap())
|
||||
gl->swapBuffers(window);
|
||||
d->fireFrameSwapped();
|
||||
} else {
|
||||
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame, 1);
|
||||
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
|
||||
QQuickProfiler::SceneGraphRenderLoopSync, 1);
|
||||
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window not ready, skipping render";
|
||||
}
|
||||
|
||||
|
@ -659,7 +662,8 @@ void QSGRenderThread::syncAndRender()
|
|||
int(threadTimer.elapsed() - renderTime / 1000000));
|
||||
|
||||
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame);
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
|
||||
QQuickProfiler::SceneGraphRenderLoopSwap);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1164,7 +1168,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
|
|||
|
||||
if (profileFrames)
|
||||
polishTime = timer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
|
||||
QQuickProfiler::SceneGraphPolishAndSyncPolish);
|
||||
|
||||
w->updateDuringSync = false;
|
||||
|
||||
|
@ -1179,7 +1184,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
|
|||
qCDebug(QSG_LOG_RENDERLOOP) << "- wait for sync";
|
||||
if (profileFrames)
|
||||
waitTime = timer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
|
||||
QQuickProfiler::SceneGraphPolishAndSyncWait);
|
||||
w->thread->waitCondition.wait(&w->thread->mutex);
|
||||
m_lockedForSync = false;
|
||||
w->thread->mutex.unlock();
|
||||
|
@ -1187,7 +1193,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
|
|||
|
||||
if (profileFrames)
|
||||
syncTime = timer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
|
||||
QQuickProfiler::SceneGraphPolishAndSyncSync);
|
||||
|
||||
if (m_animation_timer == 0 && m_animation_driver->isRunning()) {
|
||||
qCDebug(QSG_LOG_RENDERLOOP) << "- advancing animations";
|
||||
|
@ -1208,7 +1215,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
|
|||
<< ", animations=" << (timer.nsecsElapsed() - syncTime) / 1000000
|
||||
<< " - (on Gui thread) " << window;
|
||||
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync);
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync,
|
||||
QQuickProfiler::SceneGraphPolishAndSyncAnimations);
|
||||
}
|
||||
|
||||
bool QSGThreadedRenderLoop::event(QEvent *e)
|
||||
|
|
|
@ -67,9 +67,9 @@ static QElapsedTimer qsg_render_timer;
|
|||
if (QSG_LOG_TIME_RENDERLOOP().isDebugEnabled()) \
|
||||
sampleName = qsg_render_timer.nsecsElapsed(); \
|
||||
|
||||
#define QSG_RENDER_TIMING_SAMPLE(frameType, sampleName) \
|
||||
#define QSG_RENDER_TIMING_SAMPLE(frameType, sampleName, position) \
|
||||
QSG_LOG_TIME_SAMPLE(sampleName) \
|
||||
Q_QUICK_SG_PROFILE_RECORD(frameType);
|
||||
Q_QUICK_SG_PROFILE_RECORD(frameType, position);
|
||||
|
||||
|
||||
QSGWindowsRenderLoop::QSGWindowsRenderLoop()
|
||||
|
@ -395,7 +395,7 @@ void QSGWindowsRenderLoop::render()
|
|||
"animations ticked in %dms",
|
||||
int((qsg_render_timer.nsecsElapsed() - time_start)/1000000));
|
||||
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphWindowsAnimations);
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphWindowsAnimations, 1);
|
||||
|
||||
// It is not given that animations triggered another maybeUpdate()
|
||||
// and thus another render pass, so to keep things running,
|
||||
|
@ -446,22 +446,26 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
|
|||
d->polishItems();
|
||||
QSG_LOG_TIME_SAMPLE(time_polished);
|
||||
Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
|
||||
QQuickProfiler::SceneGraphRenderLoopFrame);
|
||||
QQuickProfiler::SceneGraphRenderLoopFrame,
|
||||
QQuickProfiler::SceneGraphPolishPolish);
|
||||
|
||||
emit window->afterAnimating();
|
||||
|
||||
RLDEBUG(" - syncing");
|
||||
d->syncSceneGraph();
|
||||
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_synced);
|
||||
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_synced,
|
||||
QQuickProfiler::SceneGraphRenderLoopSync);
|
||||
|
||||
RLDEBUG(" - rendering");
|
||||
d->renderSceneGraph(window->size());
|
||||
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_rendered);
|
||||
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_rendered,
|
||||
QQuickProfiler::SceneGraphRenderLoopRender);
|
||||
|
||||
RLDEBUG(" - swapping");
|
||||
if (!d->customRenderStage || !d->customRenderStage->swap())
|
||||
m_gl->swapBuffers(window);
|
||||
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_swapped);
|
||||
QSG_RENDER_TIMING_SAMPLE(QQuickProfiler::SceneGraphRenderLoopFrame, time_swapped,
|
||||
QQuickProfiler::SceneGraphRenderLoopSwap);
|
||||
|
||||
RLDEBUG(" - frameDone");
|
||||
d->fireFrameSwapped();
|
||||
|
@ -474,7 +478,8 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
|
|||
<< ", swap=" << (time_swapped - time_rendered) / 1000000
|
||||
<< " - " << window;
|
||||
|
||||
Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphRenderLoopFrame);
|
||||
Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphRenderLoopFrame,
|
||||
QQuickProfiler::SceneGraphRenderLoopSwap);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -394,9 +394,12 @@ void Atlas::bind(QSGTexture::Filtering filtering)
|
|||
bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled();
|
||||
if (profileFrames)
|
||||
qsg_renderer_timer.start();
|
||||
// Skip bind, convert, swizzle; they're irrelevant
|
||||
|
||||
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
|
||||
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, 3);
|
||||
|
||||
// Skip bind, convert, swizzle; they're irrelevant
|
||||
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
|
||||
QQuickProfiler::SceneGraphTexturePrepareStart, 3);
|
||||
|
||||
Texture *t = m_pending_uploads.at(i);
|
||||
if (m_externalFormat == GL_BGRA &&
|
||||
|
@ -414,10 +417,14 @@ void Atlas::bind(QSGTexture::Filtering filtering)
|
|||
<< "ms (" << t->textureSize().width() << "x"
|
||||
<< t->textureSize().height() << ")";
|
||||
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
|
||||
QQuickProfiler::SceneGraphTexturePrepareUpload);
|
||||
|
||||
// Skip mipmap; unused
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare);
|
||||
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, 1);
|
||||
Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphTexturePrepare);
|
||||
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
|
||||
QQuickProfiler::SceneGraphTexturePrepareUpload, 1);
|
||||
Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphTexturePrepare,
|
||||
QQuickProfiler::SceneGraphTexturePrepareMipmap);
|
||||
}
|
||||
|
||||
GLenum f = filtering == QSGTexture::Nearest ? GL_NEAREST : GL_LINEAR;
|
||||
|
|
|
@ -652,7 +652,8 @@ void QSGPlainTexture::bind()
|
|||
(int) qsg_renderer_timer.elapsed(),
|
||||
m_texture_size.width(),
|
||||
m_texture_size.height());
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTextureDeletion);
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTextureDeletion,
|
||||
QQuickProfiler::SceneGraphTextureDeletionDelete);
|
||||
}
|
||||
m_texture_id = 0;
|
||||
m_texture_size = QSize();
|
||||
|
@ -668,7 +669,8 @@ void QSGPlainTexture::bind()
|
|||
qint64 bindTime = 0;
|
||||
if (profileFrames)
|
||||
bindTime = qsg_renderer_timer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
|
||||
QQuickProfiler::SceneGraphTexturePrepareBind);
|
||||
|
||||
// ### TODO: check for out-of-memory situations...
|
||||
|
||||
|
@ -709,7 +711,8 @@ void QSGPlainTexture::bind()
|
|||
qint64 convertTime = 0;
|
||||
if (profileFrames)
|
||||
convertTime = qsg_renderer_timer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
|
||||
QQuickProfiler::SceneGraphTexturePrepareConvert);
|
||||
|
||||
updateBindOptions(m_dirty_bind_options);
|
||||
|
||||
|
@ -752,14 +755,16 @@ void QSGPlainTexture::bind()
|
|||
qint64 swizzleTime = 0;
|
||||
if (profileFrames)
|
||||
swizzleTime = qsg_renderer_timer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
|
||||
QQuickProfiler::SceneGraphTexturePrepareSwizzle);
|
||||
|
||||
funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_texture_size.width(), m_texture_size.height(), 0, externalFormat, GL_UNSIGNED_BYTE, tmp.constBits());
|
||||
|
||||
qint64 uploadTime = 0;
|
||||
if (profileFrames)
|
||||
uploadTime = qsg_renderer_timer.nsecsElapsed();
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare);
|
||||
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
|
||||
QQuickProfiler::SceneGraphTexturePrepareUpload);
|
||||
|
||||
if (mipmapFiltering() != QSGTexture::None) {
|
||||
funcs->glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
@ -782,7 +787,8 @@ void QSGPlainTexture::bind()
|
|||
int((mipmapTime - uploadTime)/1000000),
|
||||
m_texture_size != m_image.size() ? " (scaled to GL_MAX_TEXTURE_SIZE)" : "");
|
||||
}
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTexturePrepare);
|
||||
Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphTexturePrepare,
|
||||
QQuickProfiler::SceneGraphTexturePrepareMipmap);
|
||||
|
||||
m_texture_rect = QRectF(0, 0, 1, 1);
|
||||
|
||||
|
|
|
@ -71,37 +71,52 @@ QT_BEGIN_NAMESPACE
|
|||
#define Q_QUICK_PROFILE(feature, Method)\
|
||||
Q_QUICK_PROFILE_IF_ENABLED(feature, QQuickProfiler::Method)
|
||||
|
||||
// Record current timestamp for \a Type at position 0.
|
||||
#define Q_QUICK_SG_PROFILE_START(Type)\
|
||||
Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\
|
||||
(QQuickProfiler::startSceneGraphFrame<Type>()))
|
||||
|
||||
#define Q_QUICK_SG_PROFILE_RECORD(Type)\
|
||||
// Record current timestamp for \a Type at \a position.
|
||||
#define Q_QUICK_SG_PROFILE_RECORD(Type, position)\
|
||||
Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\
|
||||
(QQuickProfiler::recordSceneGraphTimestamp<Type>()))
|
||||
(QQuickProfiler::recordSceneGraphTimestamp<Type>(position)))
|
||||
|
||||
#define Q_QUICK_SG_PROFILE_SKIP(Type, Skip)\
|
||||
// Use the timestamp for \a Type at position \a position and repeat it \a Skip times in subsequent
|
||||
// positions.
|
||||
#define Q_QUICK_SG_PROFILE_SKIP(Type, position, Skip)\
|
||||
Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\
|
||||
(QQuickProfiler::skipSceneGraphTimestamps<Type, Skip>()))
|
||||
(QQuickProfiler::skipSceneGraphTimestamps<Type, Skip>(position)))
|
||||
|
||||
// Record current timestamp for both \a Type1 and \a Type2 at position 0.
|
||||
#define Q_QUICK_SG_PROFILE_START_SYNCHRONIZED(Type1, Type2)\
|
||||
Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\
|
||||
(QQuickProfiler::startSceneGraphFrame<Type1, Type2>()))
|
||||
|
||||
#define Q_QUICK_SG_PROFILE_SWITCH(Type1, Type2) \
|
||||
// report \a Type1, using the current timestamp at \a position, and switch to \a Typ2, using
|
||||
// the current timestamp at position 0.
|
||||
#define Q_QUICK_SG_PROFILE_SWITCH(Type1, Type2, position)\
|
||||
Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\
|
||||
(QQuickProfiler::reportSceneGraphFrame<Type1, true, Type2>()))
|
||||
(QQuickProfiler::reportSceneGraphFrame<Type1, true, Type2>(\
|
||||
position)))
|
||||
|
||||
#define Q_QUICK_SG_PROFILE_REPORT(Type)\
|
||||
// report \a Type, using data points 0 to \a position, including \a position.
|
||||
#define Q_QUICK_SG_PROFILE_REPORT(Type, position)\
|
||||
Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\
|
||||
(QQuickProfiler::reportSceneGraphFrame<Type, false>()))
|
||||
(QQuickProfiler::reportSceneGraphFrame<Type, false>(position)))
|
||||
|
||||
#define Q_QUICK_SG_PROFILE_END(Type)\
|
||||
// report \a Type, using data points 0 to \a position, including \a position, and setting the
|
||||
// timestamp at \a position to the current one.
|
||||
#define Q_QUICK_SG_PROFILE_END(Type, position)\
|
||||
Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\
|
||||
(QQuickProfiler::reportSceneGraphFrame<Type, true>()))
|
||||
(QQuickProfiler::reportSceneGraphFrame<Type, true>(position)))
|
||||
|
||||
#define Q_QUICK_SG_PROFILE_END_WITH_PAYLOAD(Type, Payload)\
|
||||
// report \a Type, using data points 0 to \a position, including \a position, and setting the
|
||||
// timestamp at \a position to the current one. Remaining data points up to position 5 are filled
|
||||
// with \a Payload.
|
||||
#define Q_QUICK_SG_PROFILE_END_WITH_PAYLOAD(Type, position, Payload)\
|
||||
Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\
|
||||
(QQuickProfiler::reportSceneGraphFrame<Type, true>(Payload)))
|
||||
(QQuickProfiler::reportSceneGraphFrame<Type, true>(position,\
|
||||
Payload)))
|
||||
|
||||
|
||||
#define Q_QUICK_INPUT_PROFILE(Type, DetailType, A, B)\
|
||||
|
@ -182,7 +197,6 @@ private:
|
|||
template<uint size>
|
||||
struct TimingData {
|
||||
qint64 values[size][s_numSceneGraphTimings + 1];
|
||||
int offsets[size];
|
||||
};
|
||||
|
||||
QThreadStorage<TimingData<NumRenderThreadFrameTypes> > renderThreadTimings;
|
||||
|
@ -197,15 +211,6 @@ public:
|
|||
else
|
||||
return guiThreadTimings.values[type - NumRenderThreadFrameTypes];
|
||||
}
|
||||
|
||||
template<SceneGraphFrameType type>
|
||||
int &offset()
|
||||
{
|
||||
if (type < NumRenderThreadFrameTypes)
|
||||
return renderThreadTimings.localData().offsets[type];
|
||||
else
|
||||
return guiThreadTimings.offsets[type - NumRenderThreadFrameTypes];
|
||||
}
|
||||
};
|
||||
|
||||
class Q_QUICK_PRIVATE_EXPORT QQuickProfiler : public QObject, public QQmlProfilerDefinitions {
|
||||
|
@ -217,6 +222,59 @@ public:
|
|||
RenderThread
|
||||
};
|
||||
|
||||
enum SceneGraphContextStage {
|
||||
SceneGraphContextStart,
|
||||
SceneGraphContextMaterialCompile
|
||||
};
|
||||
|
||||
enum SceneGraphRendererStage {
|
||||
SceneGraphRendererStart,
|
||||
SceneGraphRendererPreprocess,
|
||||
SceneGraphRendererUpdate,
|
||||
SceneGraphRendererBinding,
|
||||
SceneGraphRendererRender
|
||||
};
|
||||
|
||||
enum SceneGraphAdaptationLayerStage {
|
||||
SceneGraphAdaptationLayerStart,
|
||||
SceneGraphAdaptationLayerGlyphRender,
|
||||
SceneGraphAdaptationLayerGlyphStore
|
||||
};
|
||||
|
||||
enum SceneGraphRenderLoopStage {
|
||||
SceneGraphRenderLoopStart,
|
||||
SceneGraphRenderLoopSync,
|
||||
SceneGraphRenderLoopRender,
|
||||
SceneGraphRenderLoopSwap
|
||||
};
|
||||
|
||||
enum SceneGraphPolishStage {
|
||||
SceneGraphPolishStart,
|
||||
SceneGraphPolishPolish
|
||||
};
|
||||
|
||||
enum SceneGraphPolishAndSyncStage {
|
||||
SceneGraphPolishAndSyncStart,
|
||||
SceneGraphPolishAndSyncPolish,
|
||||
SceneGraphPolishAndSyncWait,
|
||||
SceneGraphPolishAndSyncSync,
|
||||
SceneGraphPolishAndSyncAnimations
|
||||
};
|
||||
|
||||
enum SceneGraphTexturePrepareStage {
|
||||
SceneGraphTexturePrepareStart,
|
||||
SceneGraphTexturePrepareBind,
|
||||
SceneGraphTexturePrepareConvert,
|
||||
SceneGraphTexturePrepareSwizzle,
|
||||
SceneGraphTexturePrepareUpload,
|
||||
SceneGraphTexturePrepareMipmap
|
||||
};
|
||||
|
||||
enum SceneGraphTextureDeletionStage {
|
||||
SceneGraphTextureDeletionStart,
|
||||
SceneGraphTextureDeletionDelete
|
||||
};
|
||||
|
||||
template<EventType DetailType, InputEventType InputType>
|
||||
static void inputEvent(int x, int y = 0)
|
||||
{
|
||||
|
@ -239,7 +297,6 @@ public:
|
|||
static void startSceneGraphFrame()
|
||||
{
|
||||
startSceneGraphFrame<FrameType1>();
|
||||
s_instance->m_sceneGraphData.offset<FrameType2>() = 0;
|
||||
s_instance->m_sceneGraphData.timings<FrameType2>()[0] =
|
||||
s_instance->m_sceneGraphData.timings<FrameType1>()[0];
|
||||
}
|
||||
|
@ -247,50 +304,45 @@ public:
|
|||
template<SceneGraphFrameType FrameType>
|
||||
static void startSceneGraphFrame()
|
||||
{
|
||||
s_instance->m_sceneGraphData.offset<FrameType>() = 0;
|
||||
s_instance->m_sceneGraphData.timings<FrameType>()[0] = s_instance->timestamp();
|
||||
}
|
||||
|
||||
template<SceneGraphFrameType FrameType>
|
||||
static void recordSceneGraphTimestamp()
|
||||
static void recordSceneGraphTimestamp(uint position)
|
||||
{
|
||||
s_instance->m_sceneGraphData.timings<FrameType>()
|
||||
[++s_instance->m_sceneGraphData.offset<FrameType>()] = s_instance->timestamp();
|
||||
s_instance->m_sceneGraphData.timings<FrameType>()[position] = s_instance->timestamp();
|
||||
}
|
||||
|
||||
template<SceneGraphFrameType FrameType, uint Skip>
|
||||
static void skipSceneGraphTimestamps()
|
||||
static void skipSceneGraphTimestamps(uint position)
|
||||
{
|
||||
qint64 *timings = s_instance->m_sceneGraphData.timings<FrameType>();
|
||||
const qint64 last = timings[s_instance->m_sceneGraphData.offset<FrameType>()];
|
||||
const qint64 last = timings[position];
|
||||
for (uint i = 0; i < Skip; ++i)
|
||||
timings[++s_instance->m_sceneGraphData.offset<FrameType>()] = last;
|
||||
timings[++position] = last;
|
||||
}
|
||||
|
||||
template<SceneGraphFrameType FrameType, bool Record>
|
||||
static void reportSceneGraphFrame(quint64 payload = ~0)
|
||||
static void reportSceneGraphFrame(uint position, quint64 payload = ~0)
|
||||
{
|
||||
qint64 *timings = s_instance->m_sceneGraphData.timings<FrameType>();
|
||||
int &offset = s_instance->m_sceneGraphData.offset<FrameType>();
|
||||
if (Record)
|
||||
timings[++offset] = s_instance->timestamp();
|
||||
timings[position] = s_instance->timestamp();
|
||||
s_instance->processMessage(QQuickProfilerData(
|
||||
timings[offset], 1 << SceneGraphFrame, 1 << FrameType,
|
||||
offset > 0 ? timings[1] - timings[0] : payload,
|
||||
offset > 1 ? timings[2] - timings[1] : payload,
|
||||
offset > 2 ? timings[3] - timings[2] : payload,
|
||||
offset > 3 ? timings[4] - timings[3] : payload,
|
||||
offset > 4 ? timings[5] - timings[4] : payload));
|
||||
timings[position], 1 << SceneGraphFrame, 1 << FrameType,
|
||||
position > 0 ? timings[1] - timings[0] : payload,
|
||||
position > 1 ? timings[2] - timings[1] : payload,
|
||||
position > 2 ? timings[3] - timings[2] : payload,
|
||||
position > 3 ? timings[4] - timings[3] : payload,
|
||||
position > 4 ? timings[5] - timings[4] : payload));
|
||||
}
|
||||
|
||||
template<SceneGraphFrameType FrameType, bool Record, SceneGraphFrameType SwitchTo>
|
||||
static void reportSceneGraphFrame(quint64 payload = ~0)
|
||||
static void reportSceneGraphFrame(uint position, quint64 payload = ~0)
|
||||
{
|
||||
reportSceneGraphFrame<FrameType, Record>(payload);
|
||||
s_instance->m_sceneGraphData.offset<SwitchTo>() = 0;
|
||||
reportSceneGraphFrame<FrameType, Record>(position, payload);
|
||||
s_instance->m_sceneGraphData.timings<SwitchTo>()[0] =
|
||||
s_instance->m_sceneGraphData.timings<FrameType>()
|
||||
[s_instance->m_sceneGraphData.offset<FrameType>()];
|
||||
s_instance->m_sceneGraphData.timings<FrameType>()[position];
|
||||
}
|
||||
|
||||
template<PixmapEventType PixmapState>
|
||||
|
|
|
@ -192,6 +192,8 @@ private slots:
|
|||
void withNoContext();
|
||||
void holeInPropertyData();
|
||||
|
||||
void malformedExpression();
|
||||
|
||||
signals:
|
||||
void testSignal();
|
||||
};
|
||||
|
@ -3876,6 +3878,12 @@ void tst_QJSEngine::holeInPropertyData()
|
|||
QVERIFY(ok.toBool());
|
||||
}
|
||||
|
||||
void tst_QJSEngine::malformedExpression()
|
||||
{
|
||||
QJSEngine engine;
|
||||
engine.evaluate("5%55555&&5555555\n7-0");
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QJSEngine)
|
||||
|
||||
#include "tst_qjsengine.moc"
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
QtObject {
|
||||
property ListModel model: ListModel {
|
||||
ListElement { modified: false }
|
||||
ListElement { modified: false }
|
||||
ListElement { modified: false }
|
||||
ListElement { modified: false }
|
||||
ListElement { modified: false }
|
||||
}
|
||||
|
||||
property bool isModified: {
|
||||
for (var i = 0; i < model.count; ++i) {
|
||||
if (model.get(i).modified)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
property bool success: false
|
||||
Component.onCompleted: {
|
||||
// trigger read and setup of property captures
|
||||
success = isModified
|
||||
model.setProperty(0, "modified", true)
|
||||
success = isModified
|
||||
}
|
||||
}
|
|
@ -122,6 +122,7 @@ private slots:
|
|||
void datetime_data();
|
||||
void about_to_be_signals();
|
||||
void modify_through_delegate();
|
||||
void bindingsOnGetResult();
|
||||
};
|
||||
|
||||
bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
|
||||
|
@ -1469,6 +1470,18 @@ void tst_qqmllistmodel::modify_through_delegate()
|
|||
QCOMPARE(model->data(model->index(1, 0, QModelIndex()), roleNames.key("age")).toInt(), 18);
|
||||
}
|
||||
|
||||
void tst_qqmllistmodel::bindingsOnGetResult()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
QQmlComponent component(&engine, testFileUrl("bindingsOnGetResult.qml"));
|
||||
QVERIFY2(!component.isError(), qPrintable(component.errorString()));
|
||||
|
||||
QScopedPointer<QObject> obj(component.create());
|
||||
QVERIFY(!obj.isNull());
|
||||
|
||||
QVERIFY(obj->property("success").toBool());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qqmllistmodel)
|
||||
|
||||
#include "tst_qqmllistmodel.moc"
|
||||
|
|
|
@ -89,6 +89,7 @@ private slots:
|
|||
void customValueTypeInQml();
|
||||
void gadgetInheritance();
|
||||
void toStringConversion();
|
||||
void enumProperties();
|
||||
|
||||
private:
|
||||
QQmlEngine engine;
|
||||
|
@ -1649,6 +1650,39 @@ void tst_qqmlvaluetypes::toStringConversion()
|
|||
QCOMPARE(stringConversion.toString(), StringLessGadget_to_QString(g));
|
||||
}
|
||||
|
||||
struct GadgetWithEnum
|
||||
{
|
||||
Q_GADGET
|
||||
public:
|
||||
|
||||
enum MyEnum { FirstValue, SecondValue };
|
||||
|
||||
Q_ENUM(MyEnum)
|
||||
Q_PROPERTY(MyEnum enumProperty READ enumProperty)
|
||||
|
||||
MyEnum enumProperty() const { return SecondValue; }
|
||||
};
|
||||
|
||||
void tst_qqmlvaluetypes::enumProperties()
|
||||
{
|
||||
QJSEngine engine;
|
||||
|
||||
// When creating the property cache for the gadget when MyEnum is _not_ a registered
|
||||
// meta-type, then QMetaProperty::type() will return QMetaType::Int and consequently
|
||||
// property-read meta-calls will return an int (as expected in this test). However if we
|
||||
// explicitly register the gadget, then QMetaProperty::type() will return the user-type
|
||||
// and QQmlValueTypeWrapper should still handle that and return an integer/number for the
|
||||
// enum property when it is read.
|
||||
qRegisterMetaType<GadgetWithEnum::MyEnum>();
|
||||
|
||||
GadgetWithEnum g;
|
||||
QJSValue value = engine.toScriptValue(g);
|
||||
|
||||
QJSValue enumValue = value.property("enumProperty");
|
||||
QVERIFY(enumValue.isNumber());
|
||||
QCOMPARE(enumValue.toInt(), int(g.enumProperty()));
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_qqmlvaluetypes)
|
||||
|
||||
|
|
|
@ -215,12 +215,15 @@ inline void QQmlGraphics_setParent_noEvent(QObject *object, QObject *parent)
|
|||
|
||||
void tst_creation::itemtree_notree_cpp()
|
||||
{
|
||||
std::vector<QQuickItem *> kids;
|
||||
kids.resize(30);
|
||||
QBENCHMARK {
|
||||
QQuickItem *item = new QQuickItem;
|
||||
for (int i = 0; i < 30; ++i) {
|
||||
QQuickItem *child = new QQuickItem;
|
||||
Q_UNUSED(child);
|
||||
kids[i] = child;
|
||||
}
|
||||
qDeleteAll(kids);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
@ -252,12 +255,13 @@ void tst_creation::itemtree_cpp()
|
|||
|
||||
void tst_creation::itemtree_data_cpp()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
QBENCHMARK {
|
||||
QQuickItem *item = new QQuickItem;
|
||||
for (int i = 0; i < 30; ++i) {
|
||||
QQuickItem *child = new QQuickItem;
|
||||
QQmlGraphics_setParent_noEvent(child,item);
|
||||
QQmlListReference ref(item, "data");
|
||||
QQmlListReference ref(item, "data", &engine);
|
||||
ref.append(child);
|
||||
}
|
||||
delete item;
|
||||
|
|
Loading…
Reference in New Issue