From 9c53c1dbea368bd8d65a8f7b16db160b3c25cf7d Mon Sep 17 00:00:00 2001 From: Ulf Hermann <ulf.hermann@theqtcompany.com> Date: Tue, 9 Dec 2014 14:18:05 +0100 Subject: [PATCH] QmlProfiler: Require only subset of renderer to execute render passes Like that we can easily add different renderers to use the same render passes, e.g. for the overview. Change-Id: Ib7dcb77a45e74488971011310f53f7639286768d Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com> --- src/plugins/qmlprofiler/qmlprofiler.pro | 7 +- src/plugins/qmlprofiler/qmlprofiler.qbs | 2 + .../qmlprofilerbindingloopsrenderpass.cpp | 2 +- .../qmlprofilerbindingloopsrenderpass.h | 4 +- .../qmlprofiler/timelineabstractrenderer.cpp | 200 ++++++++++++++ .../qmlprofiler/timelineabstractrenderer.h | 99 +++++++ .../qmlprofiler/timelineabstractrenderer_p.h | 60 ++++ .../qmlprofiler/timelineitemsrenderpass.cpp | 11 +- .../qmlprofiler/timelineitemsrenderpass.h | 4 +- .../qmlprofiler/timelinenotesrenderpass.cpp | 2 +- .../qmlprofiler/timelinenotesrenderpass.h | 4 +- .../qmlprofiler/timelineoverviewrenderer_p.h | 5 + src/plugins/qmlprofiler/timelinerenderer.cpp | 261 +----------------- src/plugins/qmlprofiler/timelinerenderer.h | 42 +-- src/plugins/qmlprofiler/timelinerenderer_p.h | 16 +- src/plugins/qmlprofiler/timelinerenderpass.h | 5 +- .../qmlprofiler/timelinerenderstate.cpp | 92 ++++++ src/plugins/qmlprofiler/timelinerenderstate.h | 5 + .../timelineselectionrenderpass.cpp | 6 +- .../qmlprofiler/timelineselectionrenderpass.h | 4 +- 20 files changed, 505 insertions(+), 326 deletions(-) create mode 100644 src/plugins/qmlprofiler/timelineabstractrenderer.cpp create mode 100644 src/plugins/qmlprofiler/timelineabstractrenderer.h create mode 100644 src/plugins/qmlprofiler/timelineabstractrenderer_p.h create mode 100644 src/plugins/qmlprofiler/timelineoverviewrenderer_p.h diff --git a/src/plugins/qmlprofiler/qmlprofiler.pro b/src/plugins/qmlprofiler/qmlprofiler.pro index a2ab78e8be2..1fa2e2e7b2e 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.pro +++ b/src/plugins/qmlprofiler/qmlprofiler.pro @@ -41,7 +41,8 @@ SOURCES += \ timelinenotesrenderpass.cpp \ timelinerenderpass.cpp \ timelinerenderstate.cpp \ - timelinenotesmodel.cpp + timelinenotesmodel.cpp \ + timelineabstractrenderer.cpp HEADERS += \ abstractqmlprofilerrunner.h \ @@ -88,7 +89,9 @@ HEADERS += \ timelinenotesmodel.h \ timelinenotesmodel_p.h \ timelinerenderer_p.h \ - timelinerenderstate_p.h + timelinerenderstate_p.h \ + timelineabstractrenderer.h \ + timelineabstractrenderer_p.h RESOURCES += \ qml/qmlprofiler.qrc diff --git a/src/plugins/qmlprofiler/qmlprofiler.qbs b/src/plugins/qmlprofiler/qmlprofiler.qbs index 16781d605e3..e14395ccc5c 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.qbs +++ b/src/plugins/qmlprofiler/qmlprofiler.qbs @@ -50,6 +50,8 @@ QtcPlugin { "qmlprofilerviewmanager.cpp", "qmlprofilerviewmanager.h", "qv8profilerdatamodel.cpp", "qv8profilerdatamodel.h", "qv8profilereventview.h", "qv8profilereventview.cpp", + "timelineabstractrenderer.cpp", "timelineabstractrenderer.h", + "timelineabstractrenderer_p.h", "timelineitemsrenderpass.cpp", "timelineitemsrenderpass.h", "timelinemodel.cpp", "timelinemodel.h", "timelinemodel_p.h", "timelinemodelaggregator.cpp", "timelinemodelaggregator.h", diff --git a/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.cpp b/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.cpp index b5ef2651a84..758f1acbcec 100644 --- a/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.cpp @@ -149,7 +149,7 @@ void updateNodes(const QmlProfilerRangeModel *model, int from, int to, } Timeline::TimelineRenderPass::State *QmlProfilerBindingLoopsRenderPass::update( - const Timeline::TimelineRenderer *renderer, + const Timeline::TimelineAbstractRenderer *renderer, const Timeline::TimelineRenderState *parentState, State *oldState, int indexFrom, int indexTo, bool stateChanged, qreal spacing) const { diff --git a/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.h b/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.h index 21a258433e8..3828a0f7323 100644 --- a/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.h +++ b/src/plugins/qmlprofiler/qmlprofilerbindingloopsrenderpass.h @@ -31,7 +31,7 @@ #ifndef QMLPROFILERBINDINGLOOPSRENDERPASS_H #define QMLPROFILERBINDINGLOOPSRENDERPASS_H -#include "timelinerenderer.h" +#include "timelineabstractrenderer.h" #include "timelinerenderpass.h" #include "timelinerenderstate.h" #include "qmlprofilerrangemodel.h" @@ -44,7 +44,7 @@ class QmlProfilerBindingLoopsRenderPass : public Timeline::TimelineRenderPass { public: static const QmlProfilerBindingLoopsRenderPass *instance(); - State *update(const Timeline::TimelineRenderer *renderer, + State *update(const Timeline::TimelineAbstractRenderer *renderer, const Timeline::TimelineRenderState *parentState, State *oldState, int indexFrom, int indexTo, bool stateChanged, qreal spacing) const; diff --git a/src/plugins/qmlprofiler/timelineabstractrenderer.cpp b/src/plugins/qmlprofiler/timelineabstractrenderer.cpp new file mode 100644 index 00000000000..720865692d4 --- /dev/null +++ b/src/plugins/qmlprofiler/timelineabstractrenderer.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "timelineabstractrenderer_p.h" + +namespace Timeline { + +TimelineAbstractRenderer::TimelineAbstractRendererPrivate::TimelineAbstractRendererPrivate() : + selectedItem(-1), selectionLocked(true), model(0), notes(0), zoomer(0), modelDirty(false), + rowHeightsDirty(false) +{ +} + +TimelineAbstractRenderer::TimelineAbstractRenderer(TimelineAbstractRendererPrivate &dd, + QQuickItem *parent) : + QQuickItem(parent), d_ptr(&dd) +{ +} + +int TimelineAbstractRenderer::selectedItem() const +{ + Q_D(const TimelineAbstractRenderer); + return d->selectedItem; +} + +void TimelineAbstractRenderer::setSelectedItem(int itemIndex) +{ + Q_D(TimelineAbstractRenderer); + if (d->selectedItem != itemIndex) { + d->selectedItem = itemIndex; + update(); + emit selectedItemChanged(itemIndex); + } +} + +bool TimelineAbstractRenderer::selectionLocked() const +{ + Q_D(const TimelineAbstractRenderer); + return d->selectionLocked; +} + +void TimelineAbstractRenderer::setSelectionLocked(bool locked) +{ + Q_D(TimelineAbstractRenderer); + if (d->selectionLocked != locked) { + d->selectionLocked = locked; + update(); + emit selectionLockedChanged(locked); + } +} + +TimelineModel *TimelineAbstractRenderer::model() const +{ + Q_D(const TimelineAbstractRenderer); + return d->model; +} + +void TimelineAbstractRenderer::setModel(TimelineModel *model) +{ + Q_D(TimelineAbstractRenderer); + if (d->model == model) + return; + + if (d->model) { + disconnect(d->model, &TimelineModel::expandedChanged, this, &QQuickItem::update); + disconnect(d->model, &TimelineModel::hiddenChanged, this, &QQuickItem::update); + disconnect(d->model, &TimelineModel::expandedRowHeightChanged, + this, &TimelineAbstractRenderer::setRowHeightsDirty); + disconnect(d->model, &TimelineModel::emptyChanged, + this, &TimelineAbstractRenderer::setModelDirty); + } + + d->model = model; + if (d->model) { + connect(d->model, &TimelineModel::expandedChanged, this, &QQuickItem::update); + connect(d->model, &TimelineModel::hiddenChanged, this, &QQuickItem::update); + connect(d->model, &TimelineModel::expandedRowHeightChanged, + this, &TimelineAbstractRenderer::setRowHeightsDirty); + connect(d->model, &TimelineModel::emptyChanged, + this, &TimelineAbstractRenderer::setModelDirty); + d->renderPasses = d->model->supportedRenderPasses(); + } + + setModelDirty(); + emit modelChanged(d->model); +} + +TimelineNotesModel *TimelineAbstractRenderer::notes() const +{ + Q_D(const TimelineAbstractRenderer); + return d->notes; +} + +void TimelineAbstractRenderer::setNotes(TimelineNotesModel *notes) +{ + Q_D(TimelineAbstractRenderer); + if (d->notes == notes) + return; + + if (d->notes) + disconnect(d->notes, &TimelineNotesModel::changed, + this, &TimelineAbstractRenderer::setNotesDirty); + + d->notes = notes; + if (d->notes) + connect(d->notes, &TimelineNotesModel::changed, + this, &TimelineAbstractRenderer::setNotesDirty); + + emit notesChanged(d->notes); + update(); +} + +TimelineZoomControl *TimelineAbstractRenderer::zoomer() const +{ + Q_D(const TimelineAbstractRenderer); + return d->zoomer; +} + +void TimelineAbstractRenderer::setZoomer(TimelineZoomControl *zoomer) +{ + Q_D(TimelineAbstractRenderer); + if (zoomer != d->zoomer) { + if (d->zoomer != 0) + disconnect(d->zoomer, SIGNAL(windowChanged(qint64,qint64)), this, SLOT(update())); + d->zoomer = zoomer; + if (d->zoomer != 0) + connect(d->zoomer, SIGNAL(windowChanged(qint64,qint64)), this, SLOT(update())); + emit zoomerChanged(zoomer); + update(); + } +} + +bool TimelineAbstractRenderer::modelDirty() const +{ + Q_D(const TimelineAbstractRenderer); + return d->modelDirty; +} + +bool TimelineAbstractRenderer::notesDirty() const +{ + Q_D(const TimelineAbstractRenderer); + return d->notesDirty; +} + +bool TimelineAbstractRenderer::rowHeightsDirty() const +{ + Q_D(const TimelineAbstractRenderer); + return d->rowHeightsDirty; +} + +void TimelineAbstractRenderer::setModelDirty() +{ + Q_D(TimelineAbstractRenderer); + d->modelDirty = true; + update(); +} + +void TimelineAbstractRenderer::setRowHeightsDirty() +{ + Q_D(TimelineAbstractRenderer); + d->rowHeightsDirty = true; + update(); +} + +void TimelineAbstractRenderer::setNotesDirty() +{ + Q_D(TimelineAbstractRenderer); + d->notesDirty = true; + update(); +} + +} // namespace Timeline + diff --git a/src/plugins/qmlprofiler/timelineabstractrenderer.h b/src/plugins/qmlprofiler/timelineabstractrenderer.h new file mode 100644 index 00000000000..ac446ad167e --- /dev/null +++ b/src/plugins/qmlprofiler/timelineabstractrenderer.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef TIMELINEABSTRACTRENDERER_H +#define TIMELINEABSTRACTRENDERER_H + +#include <QQuickItem> + +#include <QSGTransformNode> +#include <QQuickItem> +#include "timelinezoomcontrol.h" +#include "timelinemodel.h" +#include "timelinenotesmodel.h" +#include "timelinerenderpass.h" + +namespace Timeline { + +class TimelineRenderPass; +class TimelineRenderState; + +class TimelineAbstractRenderer : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(Timeline::TimelineModel *model READ model WRITE setModel NOTIFY modelChanged) + Q_PROPERTY(Timeline::TimelineNotesModel *notes READ notes WRITE setNotes NOTIFY notesChanged) + Q_PROPERTY(Timeline::TimelineZoomControl *zoomer READ zoomer WRITE setZoomer NOTIFY zoomerChanged) + Q_PROPERTY(bool selectionLocked READ selectionLocked WRITE setSelectionLocked NOTIFY selectionLockedChanged) + Q_PROPERTY(int selectedItem READ selectedItem WRITE setSelectedItem NOTIFY selectedItemChanged) + +public: + bool selectionLocked() const; + int selectedItem() const; + + TimelineModel *model() const; + void setModel(TimelineModel *model); + + TimelineNotesModel *notes() const; + void setNotes(TimelineNotesModel *notes); + + TimelineZoomControl *zoomer() const; + void setZoomer(TimelineZoomControl *zoomer); + + bool modelDirty() const; + bool notesDirty() const; + bool rowHeightsDirty() const; + +signals: + void modelChanged(const TimelineModel *model); + void notesChanged(TimelineNotesModel *notes); + void zoomerChanged(TimelineZoomControl *zoomer); + void selectionLockedChanged(bool locked); + void selectedItemChanged(int itemIndex); + +public slots: + void setSelectedItem(int itemIndex); + void setSelectionLocked(bool locked); + + void setModelDirty(); + void setNotesDirty(); + void setRowHeightsDirty(); + +protected: + class TimelineAbstractRendererPrivate; + TimelineAbstractRenderer(TimelineAbstractRendererPrivate &dd, QQuickItem *parent = 0); + TimelineAbstractRendererPrivate *d_ptr; + Q_DECLARE_PRIVATE(TimelineAbstractRenderer) +}; + +} // namespace Timeline + + +#endif // TIMELINEABSTRACTRENDERER_H diff --git a/src/plugins/qmlprofiler/timelineabstractrenderer_p.h b/src/plugins/qmlprofiler/timelineabstractrenderer_p.h new file mode 100644 index 00000000000..dfe881675a2 --- /dev/null +++ b/src/plugins/qmlprofiler/timelineabstractrenderer_p.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef TIMELINEABSTRACTRENDERER_P_H +#define TIMELINEABSTRACTRENDERER_P_H + +#include "timelineabstractrenderer.h" + +namespace Timeline { + +class TimelineAbstractRenderer::TimelineAbstractRendererPrivate { +public: + TimelineAbstractRendererPrivate(); + + int selectedItem; + bool selectionLocked; + TimelineModel *model; + TimelineNotesModel *notes; + TimelineZoomControl *zoomer; + + bool modelDirty; + bool rowHeightsDirty; + bool notesDirty; + + QList<const TimelineRenderPass *> renderPasses; + + +}; + +} + +#endif // TIMELINEABSTRACTRENDERER_P_H + diff --git a/src/plugins/qmlprofiler/timelineitemsrenderpass.cpp b/src/plugins/qmlprofiler/timelineitemsrenderpass.cpp index e1b6fa3fdee..98d2ef4caf8 100644 --- a/src/plugins/qmlprofiler/timelineitemsrenderpass.cpp +++ b/src/plugins/qmlprofiler/timelineitemsrenderpass.cpp @@ -190,10 +190,9 @@ public: virtual ~TimelineExpandedRowNode() {} }; -static void updateNodes(int from, int to, const TimelineRenderer *renderer, +static void updateNodes(int from, int to, const TimelineModel *model, const TimelineRenderState *parentState, TimelineItemsRenderPassState *state) { - const TimelineModel *model = renderer->model(); float defaultRowHeight = TimelineModel::defaultRowHeight(); QVector<TimelineItemsGeometry> expandedPerRow(model->expandedRowCount()); @@ -274,7 +273,7 @@ const TimelineItemsRenderPass *TimelineItemsRenderPass::instance() return &pass; } -TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineRenderer *renderer, +TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState, State *oldState, int indexFrom, int indexTo, bool stateChanged, @@ -315,16 +314,16 @@ TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineRendere for (int i = indexFrom; i < state->indexFrom; i+= TimelineItemsGeometry::maxEventsPerNode) updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, state->indexFrom), - renderer, parentState, state); + model, parentState, state); } if (indexTo > state->indexTo) { for (int i = state->indexTo; i < indexTo; i+= TimelineItemsGeometry::maxEventsPerNode) - updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, indexTo), renderer, + updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, indexTo), model, parentState, state); } } else { for (int i = indexFrom; i < indexTo; i+= TimelineItemsGeometry::maxEventsPerNode) - updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, indexTo), renderer, + updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, indexTo), model, parentState, state); } diff --git a/src/plugins/qmlprofiler/timelineitemsrenderpass.h b/src/plugins/qmlprofiler/timelineitemsrenderpass.h index 09b25b08d6c..06994333c08 100644 --- a/src/plugins/qmlprofiler/timelineitemsrenderpass.h +++ b/src/plugins/qmlprofiler/timelineitemsrenderpass.h @@ -31,7 +31,7 @@ #ifndef TIMELINEITEMSRENDERPASS_H #define TIMELINEITEMSRENDERPASS_H -#include "timelinerenderer.h" +#include "timelineabstractrenderer.h" #include "timelinerenderpass.h" #include <QSGMaterial> @@ -41,7 +41,7 @@ class TimelineItemsRenderPass : public TimelineRenderPass { public: static const TimelineItemsRenderPass *instance(); - State *update(const TimelineRenderer *renderer, const TimelineRenderState *parentState, + State *update(const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState, State *state, int firstIndex, int lastIndex, bool stateChanged, qreal spacing) const; protected: diff --git a/src/plugins/qmlprofiler/timelinenotesrenderpass.cpp b/src/plugins/qmlprofiler/timelinenotesrenderpass.cpp index b6b33217677..0dba68828f1 100644 --- a/src/plugins/qmlprofiler/timelinenotesrenderpass.cpp +++ b/src/plugins/qmlprofiler/timelinenotesrenderpass.cpp @@ -96,7 +96,7 @@ TimelineNotesRenderPass::TimelineNotesRenderPass() { } -TimelineRenderPass::State *TimelineNotesRenderPass::update(const TimelineRenderer *renderer, +TimelineRenderPass::State *TimelineNotesRenderPass::update(const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState, State *oldState, int firstIndex, int lastIndex, bool stateChanged, diff --git a/src/plugins/qmlprofiler/timelinenotesrenderpass.h b/src/plugins/qmlprofiler/timelinenotesrenderpass.h index e6bf5295cac..0084d899d17 100644 --- a/src/plugins/qmlprofiler/timelinenotesrenderpass.h +++ b/src/plugins/qmlprofiler/timelinenotesrenderpass.h @@ -31,7 +31,7 @@ #ifndef TIMELINENOTESRENDERPASS_H #define TIMELINENOTESRENDERPASS_H -#include "timelinerenderer.h" +#include "timelineabstractrenderer.h" #include <QSGMaterial> namespace Timeline { @@ -41,7 +41,7 @@ class TimelineNotesRenderPass : public TimelineRenderPass public: static const TimelineNotesRenderPass *instance(); - State *update(const TimelineRenderer *renderer, const TimelineRenderState *parentState, + State *update(const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState, State *oldState, int firstIndex, int lastIndex, bool stateChanged, qreal spacing) const; diff --git a/src/plugins/qmlprofiler/timelineoverviewrenderer_p.h b/src/plugins/qmlprofiler/timelineoverviewrenderer_p.h new file mode 100644 index 00000000000..2b62955e709 --- /dev/null +++ b/src/plugins/qmlprofiler/timelineoverviewrenderer_p.h @@ -0,0 +1,5 @@ +#ifndef TIMELINEOVERLAYRENDERER_P_H +#define TIMELINEOVERLAYRENDERER_P_H + +#endif // TIMELINEOVERLAYRENDERER_P_H + diff --git a/src/plugins/qmlprofiler/timelinerenderer.cpp b/src/plugins/qmlprofiler/timelinerenderer.cpp index 703c567fa87..69141399c5c 100644 --- a/src/plugins/qmlprofiler/timelinerenderer.cpp +++ b/src/plugins/qmlprofiler/timelinerenderer.cpp @@ -51,141 +51,19 @@ namespace Timeline { TimelineRenderer::TimelineRendererPrivate::TimelineRendererPrivate(TimelineRenderer *q) : - model(0), zoomer(0), notes(0), selectedItem(-1), selectionLocked(true), modelDirty(false), - rowHeightsDirty(false), rowCountsDirty(false), lastState(0), q_ptr(q) + lastState(0), q_ptr(q) { resetCurrentSelection(); } TimelineRenderer::TimelineRenderer(QQuickItem *parent) : - QQuickItem(parent), d_ptr(new TimelineRendererPrivate(this)) + TimelineAbstractRenderer(*(new TimelineRendererPrivate(this)), parent) { setFlag(QQuickItem::ItemHasContents); setAcceptedMouseButtons(Qt::LeftButton); setAcceptHoverEvents(true); } -bool TimelineRenderer::selectionLocked() const -{ - Q_D(const TimelineRenderer); - return d->selectionLocked; -} - -int TimelineRenderer::selectedItem() const -{ - Q_D(const TimelineRenderer); - return d->selectedItem; -} - -TimelineModel *TimelineRenderer::model() const -{ - Q_D(const TimelineRenderer); - return d->model; -} - -void TimelineRenderer::setModel(TimelineModel *model) -{ - Q_D(TimelineRenderer); - if (d->model == model) - return; - - if (d->model) { - disconnect(d->model, SIGNAL(expandedChanged()), this, SLOT(update())); - disconnect(d->model, SIGNAL(hiddenChanged()), this, SLOT(update())); - disconnect(d->model, SIGNAL(expandedRowHeightChanged(int,int)), - this, SLOT(setRowHeightsDirty())); - disconnect(d->model, SIGNAL(emptyChanged()), this, SLOT(setModelDirty())); - disconnect(d->model, SIGNAL(expandedRowCountChanged()), this, SLOT(setRowCountsDirty())); - disconnect(d->model, SIGNAL(collapsedRowCountChanged()), this, SLOT(setRowCountsDirty())); - } - - d->model = model; - if (d->model) { - connect(d->model, SIGNAL(expandedChanged()), this, SLOT(update())); - connect(d->model, SIGNAL(hiddenChanged()), this, SLOT(update())); - connect(d->model, SIGNAL(expandedRowHeightChanged(int,int)), - this, SLOT(setRowHeightsDirty())); - connect(d->model, SIGNAL(emptyChanged()), this, SLOT(setModelDirty())); - connect(d->model, SIGNAL(expandedRowCountChanged()), this, SLOT(setRowCountsDirty())); - connect(d->model, SIGNAL(collapsedRowCountChanged()), this, SLOT(setRowCountsDirty())); - d->renderPasses = d->model->supportedRenderPasses(); - } - - setModelDirty(); - setRowHeightsDirty(); - setRowCountsDirty(); - emit modelChanged(d->model); -} - -TimelineZoomControl *TimelineRenderer::zoomer() const -{ - Q_D(const TimelineRenderer); - return d->zoomer; -} - -void TimelineRenderer::setZoomer(TimelineZoomControl *zoomer) -{ - Q_D(TimelineRenderer); - if (zoomer != d->zoomer) { - if (d->zoomer != 0) - disconnect(d->zoomer, SIGNAL(windowChanged(qint64,qint64)), this, SLOT(update())); - d->zoomer = zoomer; - if (d->zoomer != 0) - connect(d->zoomer, SIGNAL(windowChanged(qint64,qint64)), this, SLOT(update())); - emit zoomerChanged(zoomer); - update(); - } -} - -TimelineNotesModel *TimelineRenderer::notes() const -{ - Q_D(const TimelineRenderer); - return d->notes; -} - -void TimelineRenderer::setNotes(TimelineNotesModel *notes) -{ - Q_D(TimelineRenderer); - if (d->notes == notes) - return; - - if (d->notes) - disconnect(d->notes, &TimelineNotesModel::changed, - this, &TimelineRenderer::setNotesDirty); - - d->notes = notes; - if (d->notes) - connect(d->notes, &TimelineNotesModel::changed, - this, &TimelineRenderer::setNotesDirty); - - emit notesChanged(d->notes); - update(); -} - -bool TimelineRenderer::modelDirty() const -{ - Q_D(const TimelineRenderer); - return d->modelDirty; -} - -bool TimelineRenderer::notesDirty() const -{ - Q_D(const TimelineRenderer); - return d->notesDirty; -} - -bool TimelineRenderer::rowHeightsDirty() const -{ - Q_D(const TimelineRenderer); - return d->rowHeightsDirty; -} - -bool TimelineRenderer::rowCountsDirty() const -{ - Q_D(const TimelineRenderer); - return d->rowCountsDirty; -} - void TimelineRenderer::TimelineRendererPrivate::resetCurrentSelection() { currentSelection.startTime = -1; @@ -241,14 +119,13 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node, UpdatePaintNodeData *u d->zoomer->windowDuration() <= 0) { delete node; return 0; - } else if (node == 0) { - node = new QSGTransformNode; } qreal spacing = width() / d->zoomer->windowDuration(); - if (d->modelDirty || d->rowCountsDirty) { - node->removeAllChildNodes(); + if (d->modelDirty) { + if (node) + node->removeAllChildNodes(); foreach (QVector<TimelineRenderState *> stateVector, d->renderStates) qDeleteAll(stateVector); d->renderStates.clear(); @@ -266,91 +143,23 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node, UpdatePaintNodeData *u state != d->lastState, spacing)); if (state->isEmpty()) { // new state - for (int pass = 0; pass < d->renderPasses.length(); ++pass) { - const TimelineRenderPass::State *passState = state->passState(pass); - if (!passState) - continue; - if (passState->expandedOverlay()) - state->expandedOverlayRoot()->appendChildNode(passState->expandedOverlay()); - if (passState->collapsedOverlay()) - state->collapsedOverlayRoot()->appendChildNode(passState->collapsedOverlay()); - } - - int row = 0; - for (int i = 0; i < d->model->expandedRowCount(); ++i) { - QSGTransformNode *rowNode = new QSGTransformNode; - for (int pass = 0; pass < d->renderPasses.length(); ++pass) { - const TimelineRenderPass::State *passState = state->passState(pass); - if (!passState) - continue; - const QVector<QSGNode *> &rows = passState->expandedRows(); - if (rows.length() > row) { - QSGNode *rowChildNode = rows[row]; - if (rowChildNode) - rowNode->appendChildNode(rowChildNode); - } - } - state->expandedRowRoot()->appendChildNode(rowNode); - ++row; - } - - for (int row = 0; row < d->model->collapsedRowCount(); ++row) { - QSGTransformNode *rowNode = new QSGTransformNode; - QMatrix4x4 matrix; - matrix.translate(0, row * TimelineModel::defaultRowHeight(), 0); - rowNode->setMatrix(matrix); - for (int pass = 0; pass < d->renderPasses.length(); ++pass) { - const TimelineRenderPass::State *passState = state->passState(pass); - if (!passState) - continue; - const QVector<QSGNode *> &rows = passState->collapsedRows(); - if (rows.length() > row) { - QSGNode *rowChildNode = rows[row]; - if (rowChildNode) - rowNode->appendChildNode(rowChildNode); - } - } - state->collapsedRowRoot()->appendChildNode(rowNode); - } - } - - if (d->rowHeightsDirty || state != d->lastState) { - int row = 0; - qreal offset = 0; - for (QSGNode *rowNode = state->expandedRowRoot()->firstChild(); rowNode != 0; - rowNode = rowNode->nextSibling()) { - qreal rowHeight = d->model->expandedRowHeight(row++); - QMatrix4x4 matrix; - matrix.translate(0, offset, 0); - matrix.scale(1, rowHeight / TimelineModel::defaultRowHeight(), 1); - offset += rowHeight; - static_cast<QSGTransformNode *>(rowNode)->setMatrix(matrix); - } + state->assembleNodeTree(d->model, TimelineModel::defaultRowHeight(), + TimelineModel::defaultRowHeight()); + } else if (d->rowHeightsDirty || state != d->lastState) { + state->updateExpandedRowHeights(d->model, TimelineModel::defaultRowHeight(), + TimelineModel::defaultRowHeight()); } d->modelDirty = false; d->notesDirty = false; - d->rowCountsDirty = false; d->rowHeightsDirty = false; d->lastState = state; - QSGNode *rowNode = d->model->expanded() ? state->expandedRowRoot() : state->collapsedRowRoot(); - QSGNode *overlayNode = d->model->expanded() ? state->expandedOverlayRoot() : - state->collapsedOverlayRoot(); - QMatrix4x4 matrix; matrix.translate((state->start() - d->zoomer->windowStart()) * spacing, 0, 0); matrix.scale(spacing / state->scale(), 1, 1); - QSGTransformNode *transform = static_cast<QSGTransformNode *>(node); - transform->setMatrix(matrix); - - if (node->firstChild() != rowNode || node->lastChild() != overlayNode) { - node->removeAllChildNodes(); - node->appendChildNode(rowNode); - node->appendChildNode(overlayNode); - } - return node; + return state->finalize(node, d->model->expanded(), matrix); } void TimelineRenderer::mousePressEvent(QMouseEvent *event) @@ -481,26 +290,6 @@ void TimelineRenderer::clearData() setSelectionLocked(true); } -void TimelineRenderer::setSelectedItem(int itemIndex) -{ - Q_D(TimelineRenderer); - if (d->selectedItem != itemIndex) { - d->selectedItem = itemIndex; - update(); - emit selectedItemChanged(itemIndex); - } -} - -void TimelineRenderer::setSelectionLocked(bool locked) -{ - Q_D(TimelineRenderer); - if (d->selectionLocked != locked) { - d->selectionLocked = locked; - update(); - emit selectionLockedChanged(locked); - } -} - void TimelineRenderer::selectNextFromSelectionId(int selectionId) { Q_D(TimelineRenderer); @@ -515,32 +304,4 @@ void TimelineRenderer::selectPrevFromSelectionId(int selectionId) d->selectedItem)); } -void TimelineRenderer::setModelDirty() -{ - Q_D(TimelineRenderer); - d->modelDirty = true; - update(); -} - -void TimelineRenderer::setRowHeightsDirty() -{ - Q_D(TimelineRenderer); - d->rowHeightsDirty = true; - update(); -} - -void TimelineRenderer::setNotesDirty() -{ - Q_D(TimelineRenderer); - d->notesDirty = true; - update(); -} - -void TimelineRenderer::setRowCountsDirty() -{ - Q_D(TimelineRenderer); - d->rowCountsDirty = true; - update(); -} - } // namespace Timeline diff --git a/src/plugins/qmlprofiler/timelinerenderer.h b/src/plugins/qmlprofiler/timelinerenderer.h index b772ac703a9..f996c158d37 100644 --- a/src/plugins/qmlprofiler/timelinerenderer.h +++ b/src/plugins/qmlprofiler/timelinerenderer.h @@ -36,43 +36,20 @@ #include "timelinezoomcontrol.h" #include "timelinemodel.h" #include "timelinenotesmodel.h" -#include "timelinerenderpass.h" +#include "timelineabstractrenderer.h" namespace Timeline { class TimelineRenderPass; class TimelineRenderState; -class TimelineRenderer : public QQuickItem +class TimelineRenderer : public TimelineAbstractRenderer { Q_OBJECT - Q_PROPERTY(Timeline::TimelineModel *model READ model WRITE setModel NOTIFY modelChanged) - Q_PROPERTY(Timeline::TimelineZoomControl *zoomer READ zoomer WRITE setZoomer NOTIFY zoomerChanged) - Q_PROPERTY(Timeline::TimelineNotesModel *notes READ notes WRITE setNotes NOTIFY notesChanged) - Q_PROPERTY(bool selectionLocked READ selectionLocked WRITE setSelectionLocked NOTIFY selectionLockedChanged) - Q_PROPERTY(int selectedItem READ selectedItem WRITE setSelectedItem NOTIFY selectedItemChanged) public: - explicit TimelineRenderer(QQuickItem *parent = 0); - bool selectionLocked() const; - int selectedItem() const; - - TimelineModel *model() const; - void setModel(TimelineModel *model); - - TimelineZoomControl *zoomer() const; - void setZoomer(TimelineZoomControl *zoomer); - - TimelineNotesModel *notes() const; - void setNotes(TimelineNotesModel *notes); - - bool modelDirty() const; - bool notesDirty() const; - bool rowHeightsDirty() const; - bool rowCountsDirty() const; - Q_INVOKABLE void selectNextFromSelectionId(int selectionId); Q_INVOKABLE void selectPrevFromSelectionId(int selectionId); @@ -80,25 +57,11 @@ public: // need arises. signals: - void modelChanged(const TimelineModel *model); - void zoomerChanged(TimelineZoomControl *zoomer); - void notesChanged(TimelineNotesModel *notes); - - void selectionLockedChanged(bool locked); - void selectedItemChanged(int itemIndex); void itemPressed(int pressedItem); public slots: void clearData(); - void setSelectedItem(int itemIndex); - void setSelectionLocked(bool locked); - - void setModelDirty(); - void setRowHeightsDirty(); - void setNotesDirty(); - void setRowCountsDirty(); - protected: virtual QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData); virtual void mousePressEvent(QMouseEvent *event); @@ -108,7 +71,6 @@ protected: private: class TimelineRendererPrivate; - TimelineRendererPrivate *d_ptr; Q_DECLARE_PRIVATE(TimelineRenderer) }; diff --git a/src/plugins/qmlprofiler/timelinerenderer_p.h b/src/plugins/qmlprofiler/timelinerenderer_p.h index 82de1d84a0b..3d4a2678aa0 100644 --- a/src/plugins/qmlprofiler/timelinerenderer_p.h +++ b/src/plugins/qmlprofiler/timelinerenderer_p.h @@ -32,10 +32,12 @@ #define TIMELINERENDERER_P_H #include "timelinerenderer.h" +#include "timelineabstractrenderer_p.h" namespace Timeline { -class TimelineRenderer::TimelineRendererPrivate { +class TimelineRenderer::TimelineRendererPrivate : + TimelineAbstractRenderer::TimelineAbstractRendererPrivate { public: TimelineRendererPrivate(TimelineRenderer *q); @@ -50,10 +52,6 @@ public: TimelineRenderState *findRenderState(); - TimelineModel *model; - TimelineZoomControl *zoomer; - TimelineNotesModel *notes; - struct { qint64 startTime; qint64 endTime; @@ -61,14 +59,6 @@ public: int eventIndex; } currentSelection; - int selectedItem; - bool selectionLocked; - bool modelDirty; - bool rowHeightsDirty; - bool notesDirty; - bool rowCountsDirty; - - QList<const TimelineRenderPass *> renderPasses; QVector<QVector<TimelineRenderState *> > renderStates; TimelineRenderState *lastState; diff --git a/src/plugins/qmlprofiler/timelinerenderpass.h b/src/plugins/qmlprofiler/timelinerenderpass.h index 89c1171c3cf..9068c2de85b 100644 --- a/src/plugins/qmlprofiler/timelinerenderpass.h +++ b/src/plugins/qmlprofiler/timelinerenderpass.h @@ -36,7 +36,7 @@ QT_FORWARD_DECLARE_CLASS(QSGNode) namespace Timeline { -class TimelineRenderer; +class TimelineAbstractRenderer; class TimelineRenderState; class TimelineRenderPass { @@ -50,7 +50,8 @@ public: }; virtual ~TimelineRenderPass(); - virtual State *update(const TimelineRenderer *renderer, const TimelineRenderState *parentState, + virtual State *update(const TimelineAbstractRenderer *renderer, + const TimelineRenderState *parentState, State *state, int indexFrom, int indexTo, bool stateChanged, qreal spacing) const = 0; }; diff --git a/src/plugins/qmlprofiler/timelinerenderstate.cpp b/src/plugins/qmlprofiler/timelinerenderstate.cpp index 4e6014cb387..e014f910487 100644 --- a/src/plugins/qmlprofiler/timelinerenderstate.cpp +++ b/src/plugins/qmlprofiler/timelinerenderstate.cpp @@ -134,6 +134,98 @@ bool TimelineRenderState::isEmpty() const d->collapsedOverlayRoot->childCount() == 0 && d->expandedOverlayRoot->childCount() == 0; } +void TimelineRenderState::assembleNodeTree(const TimelineModel *model, int defaultRowHeight, + int defaultRowOffset) +{ + Q_D(TimelineRenderState); + for (int pass = 0; pass < d->passes.length(); ++pass) { + const TimelineRenderPass::State *passState = d->passes[pass]; + if (!passState) + continue; + if (passState->expandedOverlay()) + d->expandedOverlayRoot->appendChildNode(passState->expandedOverlay()); + if (passState->collapsedOverlay()) + d->collapsedOverlayRoot->appendChildNode(passState->collapsedOverlay()); + } + + int row = 0; + for (int i = 0; i < model->expandedRowCount(); ++i) { + QSGTransformNode *rowNode = new QSGTransformNode; + for (int pass = 0; pass < d->passes.length(); ++pass) { + const TimelineRenderPass::State *passState = d->passes[pass]; + if (!passState) + continue; + const QVector<QSGNode *> &rows = passState->expandedRows(); + if (rows.length() > row) { + QSGNode *rowChildNode = rows[row]; + if (rowChildNode) + rowNode->appendChildNode(rowChildNode); + } + } + d->expandedRowRoot->appendChildNode(rowNode); + ++row; + } + + for (int row = 0; row < model->collapsedRowCount(); ++row) { + QSGTransformNode *rowNode = new QSGTransformNode; + QMatrix4x4 matrix; + matrix.translate(0, row * defaultRowOffset, 0); + matrix.scale(1.0, static_cast<float>(defaultRowHeight) / + static_cast<float>(TimelineModel::defaultRowHeight()), 1.0); + rowNode->setMatrix(matrix); + for (int pass = 0; pass < d->passes.length(); ++pass) { + const TimelineRenderPass::State *passState = d->passes[pass]; + if (!passState) + continue; + const QVector<QSGNode *> &rows = passState->collapsedRows(); + if (rows.length() > row) { + QSGNode *rowChildNode = rows[row]; + if (rowChildNode) + rowNode->appendChildNode(rowChildNode); + } + } + d->collapsedRowRoot->appendChildNode(rowNode); + } + + updateExpandedRowHeights(model, defaultRowHeight, defaultRowOffset); +} + +void TimelineRenderState::updateExpandedRowHeights(const TimelineModel *model, int defaultRowHeight, + int defaultRowOffset) +{ + Q_D(TimelineRenderState); + int row = 0; + qreal offset = 0; + for (QSGNode *rowNode = d->expandedRowRoot->firstChild(); rowNode != 0; + rowNode = rowNode->nextSibling()) { + qreal rowHeight = model->expandedRowHeight(row++); + QMatrix4x4 matrix; + matrix.translate(0, offset, 0); + matrix.scale(1, rowHeight / defaultRowHeight, 1); + offset += defaultRowOffset * rowHeight / defaultRowHeight; + static_cast<QSGTransformNode *>(rowNode)->setMatrix(matrix); + } +} + +QSGTransformNode *TimelineRenderState::finalize(QSGNode *oldNode, bool expanded, + const QMatrix4x4 &transform) +{ + Q_D(TimelineRenderState); + QSGNode *rowNode = expanded ? d->expandedRowRoot : d->collapsedRowRoot; + QSGNode *overlayNode = expanded ?d->expandedOverlayRoot : d->collapsedOverlayRoot; + + QSGTransformNode *node = oldNode ? static_cast<QSGTransformNode *>(oldNode) : + new QSGTransformNode; + node->setMatrix(transform); + + if (node->firstChild() != rowNode || node->lastChild() != overlayNode) { + node->removeAllChildNodes(); + node->appendChildNode(rowNode); + node->appendChildNode(overlayNode); + } + return node; +} + TimelineRenderPass::State *TimelineRenderState::passState(int i) { Q_D(TimelineRenderState); diff --git a/src/plugins/qmlprofiler/timelinerenderstate.h b/src/plugins/qmlprofiler/timelinerenderstate.h index 9d28d349e83..2333e836fb3 100644 --- a/src/plugins/qmlprofiler/timelinerenderstate.h +++ b/src/plugins/qmlprofiler/timelinerenderstate.h @@ -33,6 +33,7 @@ #include <QSGNode> #include "timelinerenderpass.h" +#include "timelinemodel.h" namespace Timeline { @@ -60,6 +61,10 @@ public: QSGNode *collapsedOverlayRoot(); bool isEmpty() const; + void assembleNodeTree(const TimelineModel *model, int defaultRowHeight, int defaultRowOffset); + void updateExpandedRowHeights(const TimelineModel *model, int defaultRowHeight, + int defaultRowOffset); + QSGTransformNode *finalize(QSGNode *oldNode, bool expanded, const QMatrix4x4 &transform); private: class TimelineRenderStatePrivate; diff --git a/src/plugins/qmlprofiler/timelineselectionrenderpass.cpp b/src/plugins/qmlprofiler/timelineselectionrenderpass.cpp index 10b674fccea..eb5cdb5b040 100644 --- a/src/plugins/qmlprofiler/timelineselectionrenderpass.cpp +++ b/src/plugins/qmlprofiler/timelineselectionrenderpass.cpp @@ -55,9 +55,9 @@ struct TimelineSelectionRenderPassState : public TimelineRenderPass::State { QSGNode *collapsedOverlay() const { return m_collapsedOverlay; } }; -TimelineRenderPass::State *TimelineSelectionRenderPass::update(const TimelineRenderer *renderer, - const TimelineRenderState *parentState, State *oldState, int firstIndex, int lastIndex, - bool stateChanged, qreal spacing) const +TimelineRenderPass::State *TimelineSelectionRenderPass::update( + const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState, + State *oldState, int firstIndex, int lastIndex, bool stateChanged, qreal spacing) const { Q_UNUSED(stateChanged); diff --git a/src/plugins/qmlprofiler/timelineselectionrenderpass.h b/src/plugins/qmlprofiler/timelineselectionrenderpass.h index 83046465fa4..f7445ac661d 100644 --- a/src/plugins/qmlprofiler/timelineselectionrenderpass.h +++ b/src/plugins/qmlprofiler/timelineselectionrenderpass.h @@ -31,7 +31,7 @@ #ifndef TIMELINESELECTIONRENDERPASS_H #define TIMELINESELECTIONRENDERPASS_H -#include "timelinerenderer.h" +#include "timelineabstractrenderer.h" #include "timelinerenderpass.h" #include "timelinerenderstate.h" @@ -42,7 +42,7 @@ class TimelineSelectionRenderPass : public TimelineRenderPass public: static const TimelineSelectionRenderPass *instance(); - State *update(const TimelineRenderer *renderer, const TimelineRenderState *parentState, + State *update(const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState, State *state, int firstIndex, int lastIndex, bool stateChanged, qreal spacing) const; -- GitLab