forked from qt-creator/qt-creator
QmlProfiler: Make overview declarative
Using the TimelineRenderer's render passes we can as well draw the overview in a nicer way without procedural painting. Change-Id: I9464f10c52988a6af10c849878e678e4958a1057 Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
This commit is contained in:
@@ -102,7 +102,6 @@ Rectangle {
|
|||||||
selectionRangeMode = false;
|
selectionRangeMode = false;
|
||||||
zoomSlider.externalUpdate = true;
|
zoomSlider.externalUpdate = true;
|
||||||
zoomSlider.value = zoomSlider.minimumValue;
|
zoomSlider.value = zoomSlider.minimumValue;
|
||||||
overview.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableButtonsBar(enable) {
|
function enableButtonsBar(enable) {
|
||||||
|
|||||||
@@ -1,186 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** 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.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
.pragma library
|
|
||||||
|
|
||||||
var models = 0;
|
|
||||||
var notes = 0;
|
|
||||||
var zoomControl = 0;
|
|
||||||
|
|
||||||
//draw background of the graph
|
|
||||||
function drawGraph(canvas, ctxt)
|
|
||||||
{
|
|
||||||
ctxt.fillStyle = "#eaeaea";
|
|
||||||
ctxt.fillRect(0, 0, canvas.width, canvas.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
//draw the actual data to be graphed
|
|
||||||
function drawData(canvas, ctxt)
|
|
||||||
{
|
|
||||||
if (!zoomControl || !models)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (var modelIndex = 0; modelIndex < models.length; ++modelIndex) {
|
|
||||||
var model = models[modelIndex];
|
|
||||||
for (var ii = canvas.offset; ii < model.count; ii += canvas.increment) {
|
|
||||||
var xx = (model.startTime(ii) - zoomControl.traceStart) * canvas.spacing;
|
|
||||||
|
|
||||||
var eventWidth = model.duration(ii) * canvas.spacing;
|
|
||||||
|
|
||||||
if (eventWidth < 1)
|
|
||||||
eventWidth = 1;
|
|
||||||
|
|
||||||
xx = Math.round(xx);
|
|
||||||
|
|
||||||
var itemHeight = model.relativeHeight(ii) * canvas.blockHeight;
|
|
||||||
var yy = (modelIndex + 1) * canvas.blockHeight - itemHeight ;
|
|
||||||
|
|
||||||
ctxt.fillStyle = model.color(ii);
|
|
||||||
ctxt.fillRect(xx, canvas.bump + yy, eventWidth, itemHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawBindingLoops(canvas, ctxt) {
|
|
||||||
ctxt.strokeStyle = "orange";
|
|
||||||
ctxt.lineWidth = 2;
|
|
||||||
var radius = 1;
|
|
||||||
for (var modelIndex = 0; modelIndex < models.length; ++modelIndex) {
|
|
||||||
var model = models[modelIndex];
|
|
||||||
for (var ii = canvas.offset - canvas.increment; ii < model.count; ii += canvas.increment) {
|
|
||||||
if (model.bindingLoopDest(ii) >= 0) {
|
|
||||||
var xcenter = Math.round(model.startTime(ii) + model.duration(ii) / 2 -
|
|
||||||
zoomControl.traceStart) * canvas.spacing;
|
|
||||||
var ycenter = Math.round(canvas.bump + canvas.blockHeight * modelIndex +
|
|
||||||
canvas.blockHeight / 2);
|
|
||||||
ctxt.beginPath();
|
|
||||||
ctxt.arc(xcenter, ycenter, radius, 0, 2*Math.PI, true);
|
|
||||||
ctxt.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawNotes(canvas, ctxt)
|
|
||||||
{
|
|
||||||
if (!zoomControl || !models || !notes || notes.count === 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var modelsById = models.reduce(function(prev, model) {
|
|
||||||
prev[model.modelId] = model;
|
|
||||||
return prev;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
// divide canvas height in 7 parts: margin, 3*line, space, dot, margin
|
|
||||||
var vertSpace = (canvas.height - canvas.bump) / 7;
|
|
||||||
|
|
||||||
ctxt.strokeStyle = "orange";
|
|
||||||
ctxt.lineWidth = 2;
|
|
||||||
for (var i = 0; i < notes.count; ++i) {
|
|
||||||
var timelineModel = notes.timelineModel(i);
|
|
||||||
var timelineIndex = notes.timelineIndex(i);
|
|
||||||
if (timelineIndex === -1)
|
|
||||||
continue;
|
|
||||||
var start = Math.max(modelsById[timelineModel].startTime(timelineIndex),
|
|
||||||
zoomControl.traceStart);
|
|
||||||
var end = Math.min(modelsById[timelineModel].endTime(timelineIndex),
|
|
||||||
zoomControl.traceEnd);
|
|
||||||
|
|
||||||
var annoX = Math.round(((start + end) / 2 - zoomControl.traceStart) * canvas.spacing);
|
|
||||||
|
|
||||||
ctxt.moveTo(annoX, canvas.bump + vertSpace)
|
|
||||||
ctxt.lineTo(annoX, canvas.bump + vertSpace * 4)
|
|
||||||
ctxt.stroke();
|
|
||||||
ctxt.moveTo(annoX, canvas.bump + vertSpace * 5);
|
|
||||||
ctxt.lineTo(annoX, canvas.bump + vertSpace * 6);
|
|
||||||
ctxt.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawTimeBar(canvas, ctxt)
|
|
||||||
{
|
|
||||||
if (!zoomControl)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var width = canvas.width;
|
|
||||||
var height = 10;
|
|
||||||
|
|
||||||
var initialBlockLength = 120;
|
|
||||||
var timePerBlock = Math.pow(2, Math.floor( Math.log( zoomControl.traceDuration / width *
|
|
||||||
initialBlockLength ) / Math.LN2 ) );
|
|
||||||
var pixelsPerBlock = timePerBlock * canvas.spacing;
|
|
||||||
var pixelsPerSection = pixelsPerBlock / 5;
|
|
||||||
var blockCount = width / pixelsPerBlock;
|
|
||||||
|
|
||||||
var realStartTime = Math.floor(zoomControl.traceStart / timePerBlock) * timePerBlock;
|
|
||||||
var realStartPos = (zoomControl.traceStart - realStartTime) * canvas.spacing;
|
|
||||||
|
|
||||||
var timePerPixel = timePerBlock/pixelsPerBlock;
|
|
||||||
|
|
||||||
ctxt.fillStyle = "#000000";
|
|
||||||
ctxt.font = "6px sans-serif";
|
|
||||||
|
|
||||||
ctxt.fillStyle = "#cccccc";
|
|
||||||
ctxt.fillRect(0, 0, width, height);
|
|
||||||
for (var ii = 0; ii < blockCount+1; ii++) {
|
|
||||||
var x = Math.floor(ii*pixelsPerBlock - realStartPos);
|
|
||||||
|
|
||||||
// block boundary
|
|
||||||
ctxt.strokeStyle = "#525252";
|
|
||||||
ctxt.beginPath();
|
|
||||||
ctxt.moveTo(x, height/2);
|
|
||||||
ctxt.lineTo(x, height);
|
|
||||||
ctxt.stroke();
|
|
||||||
|
|
||||||
// block time label
|
|
||||||
ctxt.fillStyle = "#000000";
|
|
||||||
var timeString = prettyPrintTime((ii+0.5)*timePerBlock + realStartTime);
|
|
||||||
ctxt.textAlign = "center";
|
|
||||||
ctxt.fillText(timeString, x + pixelsPerBlock/2, height/2 + 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctxt.fillStyle = "#808080";
|
|
||||||
ctxt.fillRect(0, height-1, width, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function prettyPrintTime( t )
|
|
||||||
{
|
|
||||||
if (t <= 0) return "0";
|
|
||||||
if (t<1000) return t+" ns";
|
|
||||||
t = t/1000;
|
|
||||||
if (t<1000) return t+" μs";
|
|
||||||
t = Math.floor(t/100)/10;
|
|
||||||
if (t<1000) return t+" ms";
|
|
||||||
t = Math.floor(t)/1000;
|
|
||||||
if (t<60) return t+" s";
|
|
||||||
var m = Math.floor(t/60);
|
|
||||||
t = Math.floor(t - m*60);
|
|
||||||
return m+"m"+t+"s";
|
|
||||||
}
|
|
||||||
@@ -29,39 +29,17 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
import QtQuick 2.1
|
import QtQuick 2.1
|
||||||
import "Overview.js" as Plotter
|
import TimelineOverviewRenderer 1.0
|
||||||
|
|
||||||
Canvas {
|
Rectangle {
|
||||||
id: canvas
|
id: overview
|
||||||
objectName: "Overview"
|
objectName: "Overview"
|
||||||
contextType: "2d"
|
color: parent.color
|
||||||
|
|
||||||
property QtObject modelProxy
|
property QtObject modelProxy
|
||||||
property QtObject zoomer
|
property QtObject zoomer
|
||||||
|
|
||||||
readonly property int eventsPerPass: 512
|
|
||||||
property int increment: -1
|
|
||||||
property int offset: -1
|
|
||||||
readonly property int bump: 10;
|
|
||||||
readonly property int blockHeight: (height - bump) / modelProxy.models.length;
|
|
||||||
readonly property double spacing: width / zoomer.traceDuration
|
|
||||||
|
|
||||||
// ***** properties
|
|
||||||
height: 50
|
|
||||||
property bool dataReady: false
|
|
||||||
property bool recursionGuard: false
|
property bool recursionGuard: false
|
||||||
|
|
||||||
onWidthChanged: offset = -1
|
|
||||||
|
|
||||||
// ***** functions
|
|
||||||
function clear()
|
|
||||||
{
|
|
||||||
dataReady = false;
|
|
||||||
increment = -1;
|
|
||||||
offset = -1;
|
|
||||||
requestPaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateRange() {
|
function updateRange() {
|
||||||
if (recursionGuard)
|
if (recursionGuard)
|
||||||
return;
|
return;
|
||||||
@@ -75,11 +53,6 @@ Canvas {
|
|||||||
recursionGuard = false;
|
recursionGuard = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function clamp(val, min, max) {
|
|
||||||
return Math.min(Math.max(val, min), max);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***** connections to external objects
|
|
||||||
Connections {
|
Connections {
|
||||||
target: zoomer
|
target: zoomer
|
||||||
onRangeChanged: {
|
onRangeChanged: {
|
||||||
@@ -100,90 +73,95 @@ Canvas {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
TimeDisplay {
|
||||||
target: modelProxy
|
id: timebar
|
||||||
onDataAvailable: {
|
anchors.top: parent.top
|
||||||
dataReady = true;
|
anchors.left: parent.left
|
||||||
increment = 0;
|
anchors.right: parent.right
|
||||||
var models = modelProxy.models;
|
textMargin: 2
|
||||||
for (var i = 0; i < models.length; ++i)
|
bottomBorderHeight: 0
|
||||||
increment += models[i].count;
|
topBorderHeight: 1
|
||||||
increment = Math.ceil(increment / eventsPerPass);
|
height: 10
|
||||||
offset = -1;
|
fontSize: 6
|
||||||
requestPaint();
|
labelsHeight: 10
|
||||||
}
|
color1: "#cccccc"
|
||||||
|
color2: "#cccccc"
|
||||||
|
windowStart: zoomer.traceStart
|
||||||
|
alignedWindowStart: zoomer.traceStart
|
||||||
|
rangeDuration: zoomer.traceDuration
|
||||||
|
contentX: 0
|
||||||
|
offsetX: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: modelProxy.notes
|
|
||||||
onChanged: notes.doPaint = true
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
Column {
|
||||||
id: paintTimer
|
anchors.top: timebar.bottom
|
||||||
repeat: true
|
anchors.bottom: parent.bottom
|
||||||
running: offset >= 0
|
anchors.left: parent.left
|
||||||
interval: offset == 0 ? 1000 : 14 // Larger initial delay to avoid flickering on resize
|
anchors.right: parent.right
|
||||||
onTriggered: canvas.requestPaint()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***** slots
|
id: column
|
||||||
onPaint: {
|
|
||||||
var context = (canvas.context === null) ? getContext("2d") : canvas.context;
|
|
||||||
|
|
||||||
Plotter.models = modelProxy.models;
|
Repeater {
|
||||||
Plotter.zoomControl = zoomer;
|
model: modelProxy.models
|
||||||
Plotter.notes = modelProxy.notes;
|
TimelineOverviewRenderer {
|
||||||
|
model: modelData
|
||||||
if (offset < 0) {
|
zoomer: overview.zoomer
|
||||||
context.reset();
|
notes: modelProxy.notes
|
||||||
Plotter.drawGraph(canvas, context);
|
width: column.width
|
||||||
if (dataReady) {
|
height: column.height / modelProxy.models.length
|
||||||
Plotter.drawTimeBar(canvas, context);
|
|
||||||
offset = 0;
|
|
||||||
}
|
}
|
||||||
} else if (offset < increment) {
|
|
||||||
Plotter.drawData(canvas, context);
|
|
||||||
++offset;
|
|
||||||
} else if (offset < 2 * increment) {
|
|
||||||
Plotter.drawBindingLoops(canvas, context);
|
|
||||||
++offset;
|
|
||||||
} else {
|
|
||||||
notes.doPaint = true;
|
|
||||||
offset = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Canvas {
|
Repeater {
|
||||||
property alias bump: canvas.bump
|
id: noteSigns
|
||||||
property alias spacing: canvas.spacing
|
property var modelsById: modelProxy.models.reduce(function(prev, model) {
|
||||||
property bool doPaint: false
|
prev[model.modelId] = model;
|
||||||
onDoPaintChanged: {
|
return prev;
|
||||||
if (doPaint)
|
}, {});
|
||||||
requestPaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
id: notes
|
property int vertSpace: column.height / 7
|
||||||
anchors.fill: parent
|
property color noteColor: "orange"
|
||||||
onPaint: {
|
readonly property double spacing: parent.width / zoomer.traceDuration
|
||||||
if (doPaint) {
|
|
||||||
var context = (notes.context === null) ? getContext("2d") : notes.context;
|
model: modelProxy.notes.count
|
||||||
context.reset();
|
Item {
|
||||||
Plotter.drawNotes(notes, context);
|
property int timelineIndex: modelProxy.notes.timelineIndex(index)
|
||||||
doPaint = false;
|
property int timelineModel: modelProxy.notes.timelineModel(index)
|
||||||
|
property double startTime: noteSigns.modelsById[timelineModel].startTime(timelineIndex)
|
||||||
|
property double endTime: noteSigns.modelsById[timelineModel].endTime(timelineIndex)
|
||||||
|
x: ((startTime + endTime) / 2 - zoomer.traceStart) * noteSigns.spacing
|
||||||
|
y: timebar.height + noteSigns.vertSpace
|
||||||
|
height: noteSigns.vertSpace * 5
|
||||||
|
width: 2
|
||||||
|
Rectangle {
|
||||||
|
color: noteSigns.noteColor
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
height: noteSigns.vertSpace * 3
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: noteSigns.noteColor
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
height: noteSigns.vertSpace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***** child items
|
// ***** child items
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: canvas
|
anchors.fill: parent
|
||||||
function jumpTo(posX) {
|
function jumpTo(posX) {
|
||||||
var newX = posX - rangeMover.rangeWidth / 2;
|
var newX = posX - rangeMover.rangeWidth / 2;
|
||||||
if (newX < 0)
|
if (newX < 0)
|
||||||
newX = 0;
|
newX = 0;
|
||||||
if (newX + rangeMover.rangeWidth > canvas.width)
|
if (newX + rangeMover.rangeWidth > overview.width)
|
||||||
newX = canvas.width - rangeMover.rangeWidth;
|
newX = overview.width - rangeMover.rangeWidth;
|
||||||
|
|
||||||
if (newX < rangeMover.rangeLeft) {
|
if (newX < rangeMover.rangeLeft) {
|
||||||
// Changing left border will change width, so precompute right border here.
|
// Changing left border will change width, so precompute right border here.
|
||||||
@@ -206,9 +184,9 @@ Canvas {
|
|||||||
|
|
||||||
RangeMover {
|
RangeMover {
|
||||||
id: rangeMover
|
id: rangeMover
|
||||||
visible: dataReady
|
visible: modelProxy.height > 0
|
||||||
onRangeLeftChanged: canvas.updateRange()
|
onRangeLeftChanged: overview.updateRange()
|
||||||
onRangeRightChanged: canvas.updateRange()
|
onRangeRightChanged: overview.updateRange()
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
<file>ico_edit.png</file>
|
<file>ico_edit.png</file>
|
||||||
<file>TimeMarks.qml</file>
|
<file>TimeMarks.qml</file>
|
||||||
<file>Overview.qml</file>
|
<file>Overview.qml</file>
|
||||||
<file>Overview.js</file>
|
|
||||||
<file>SelectionRange.qml</file>
|
<file>SelectionRange.qml</file>
|
||||||
<file>SelectionRangeDetails.qml</file>
|
<file>SelectionRangeDetails.qml</file>
|
||||||
<file>arrow_down.png</file>
|
<file>arrow_down.png</file>
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ SOURCES += \
|
|||||||
timelinerenderpass.cpp \
|
timelinerenderpass.cpp \
|
||||||
timelinerenderstate.cpp \
|
timelinerenderstate.cpp \
|
||||||
timelinenotesmodel.cpp \
|
timelinenotesmodel.cpp \
|
||||||
timelineabstractrenderer.cpp
|
timelineabstractrenderer.cpp \
|
||||||
|
timelineoverviewrenderer.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
abstractqmlprofilerrunner.h \
|
abstractqmlprofilerrunner.h \
|
||||||
@@ -91,7 +92,9 @@ HEADERS += \
|
|||||||
timelinerenderer_p.h \
|
timelinerenderer_p.h \
|
||||||
timelinerenderstate_p.h \
|
timelinerenderstate_p.h \
|
||||||
timelineabstractrenderer.h \
|
timelineabstractrenderer.h \
|
||||||
timelineabstractrenderer_p.h
|
timelineabstractrenderer_p.h \
|
||||||
|
timelineoverviewrenderer_p.h \
|
||||||
|
timelineoverviewrenderer.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
qml/qmlprofiler.qrc
|
qml/qmlprofiler.qrc
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ QtcPlugin {
|
|||||||
"timelinemodelaggregator.cpp", "timelinemodelaggregator.h",
|
"timelinemodelaggregator.cpp", "timelinemodelaggregator.h",
|
||||||
"timelinenotesmodel.cpp", "timelinenotesmodel.h", "timelinenotesmodel_p.h",
|
"timelinenotesmodel.cpp", "timelinenotesmodel.h", "timelinenotesmodel_p.h",
|
||||||
"timelinenotesrenderpass.cpp", "timelinenotesrenderpass.h",
|
"timelinenotesrenderpass.cpp", "timelinenotesrenderpass.h",
|
||||||
|
"timelineoverlayrenderer.cpp", "timelineoverlayrenderer.h",
|
||||||
|
"timelineoverlayrenderer_p.h",
|
||||||
"timelinerenderer.cpp", "timelinerenderer.h", "timelinerenderer_p.h",
|
"timelinerenderer.cpp", "timelinerenderer.h", "timelinerenderer_p.h",
|
||||||
"timelinerenderpass.cpp", "timelinerenderpass.h",
|
"timelinerenderpass.cpp", "timelinerenderpass.h",
|
||||||
"timelinerenderstate.cpp", "timelinerenderstate.h", "timelinerenderstate_p.h",
|
"timelinerenderstate.cpp", "timelinerenderstate.h", "timelinerenderstate_p.h",
|
||||||
@@ -73,7 +75,6 @@ QtcPlugin {
|
|||||||
"Detail.qml",
|
"Detail.qml",
|
||||||
"CategoryLabel.qml",
|
"CategoryLabel.qml",
|
||||||
"MainView.qml",
|
"MainView.qml",
|
||||||
"Overview.js",
|
|
||||||
"Overview.qml",
|
"Overview.qml",
|
||||||
"RangeDetails.qml",
|
"RangeDetails.qml",
|
||||||
"RangeMover.qml",
|
"RangeMover.qml",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "qmlprofileranimationsmodel.h"
|
#include "qmlprofileranimationsmodel.h"
|
||||||
#include "qmlprofilerrangemodel.h"
|
#include "qmlprofilerrangemodel.h"
|
||||||
#include "qmlprofilerplugin.h"
|
#include "qmlprofilerplugin.h"
|
||||||
|
#include "timelineoverviewrenderer.h"
|
||||||
|
|
||||||
// Needed for the load&save actions in the context menu
|
// Needed for the load&save actions in the context menu
|
||||||
#include <analyzerbase/ianalyzertool.h>
|
#include <analyzerbase/ianalyzertool.h>
|
||||||
@@ -100,6 +101,8 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, Analyzer::IAnalyzerT
|
|||||||
groupLayout->setSpacing(0);
|
groupLayout->setSpacing(0);
|
||||||
|
|
||||||
qmlRegisterType<Timeline::TimelineRenderer>("TimelineRenderer", 1, 0, "TimelineRenderer");
|
qmlRegisterType<Timeline::TimelineRenderer>("TimelineRenderer", 1, 0, "TimelineRenderer");
|
||||||
|
qmlRegisterType<Timeline::TimelineOverviewRenderer>("TimelineOverviewRenderer", 1, 0,
|
||||||
|
"TimelineOverviewRenderer");
|
||||||
qmlRegisterType<Timeline::TimelineZoomControl>();
|
qmlRegisterType<Timeline::TimelineZoomControl>();
|
||||||
qmlRegisterType<Timeline::TimelineModel>();
|
qmlRegisterType<Timeline::TimelineModel>();
|
||||||
qmlRegisterType<Timeline::TimelineNotesModel>();
|
qmlRegisterType<Timeline::TimelineNotesModel>();
|
||||||
|
|||||||
91
src/plugins/qmlprofiler/timelineoverviewrenderer.cpp
Normal file
91
src/plugins/qmlprofiler/timelineoverviewrenderer.cpp
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "timelineoverviewrenderer_p.h"
|
||||||
|
#include "timelinerenderstate.h"
|
||||||
|
|
||||||
|
namespace Timeline {
|
||||||
|
|
||||||
|
TimelineOverviewRenderer::TimelineOverviewRenderer(QQuickItem *parent) :
|
||||||
|
TimelineAbstractRenderer(*(new TimelineOverviewRendererPrivate), parent)
|
||||||
|
{
|
||||||
|
Q_D(TimelineOverviewRenderer);
|
||||||
|
setFlag(QQuickItem::ItemHasContents);
|
||||||
|
d->renderState = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimelineOverviewRenderer::~TimelineOverviewRenderer()
|
||||||
|
{
|
||||||
|
Q_D(TimelineOverviewRenderer);
|
||||||
|
delete d->renderState;
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGNode *TimelineOverviewRenderer::updatePaintNode(QSGNode *oldNode,
|
||||||
|
UpdatePaintNodeData *updatePaintNodeData)
|
||||||
|
{
|
||||||
|
Q_D(TimelineOverviewRenderer);
|
||||||
|
Q_UNUSED(updatePaintNodeData)
|
||||||
|
|
||||||
|
if (d->modelDirty) {
|
||||||
|
delete d->renderState;
|
||||||
|
d->renderState = 0;
|
||||||
|
d->modelDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->renderState == 0) {
|
||||||
|
d->renderState = new TimelineRenderState(d->zoomer->traceStart(), d->zoomer->traceEnd(),
|
||||||
|
1.0, d->renderPasses.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal xSpacing = width() / d->zoomer->traceDuration();
|
||||||
|
qreal ySpacing = height() / (d->model->collapsedRowCount() * TimelineModel::defaultRowHeight());
|
||||||
|
|
||||||
|
for (int i = 0; i < d->renderPasses.length(); ++i) {
|
||||||
|
d->renderState->setPassState(i, d->renderPasses[i]->update(this, d->renderState,
|
||||||
|
d->renderState->passState(i),
|
||||||
|
0, d->model->count(), true,
|
||||||
|
xSpacing));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->renderState->isEmpty())
|
||||||
|
d->renderState->assembleNodeTree(d->model, d->model->height(), 0);
|
||||||
|
|
||||||
|
d->modelDirty = false;
|
||||||
|
d->notesDirty = false;
|
||||||
|
d->rowHeightsDirty = false;
|
||||||
|
|
||||||
|
QMatrix4x4 matrix;
|
||||||
|
matrix.scale(xSpacing, ySpacing, 1);
|
||||||
|
return d->renderState->finalize(oldNode, false, matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
55
src/plugins/qmlprofiler/timelineoverviewrenderer.h
Normal file
55
src/plugins/qmlprofiler/timelineoverviewrenderer.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 TIMELINEOVERVIEWRENDERER_H
|
||||||
|
#define TIMELINEOVERVIEWRENDERER_H
|
||||||
|
|
||||||
|
#include "timelineabstractrenderer.h"
|
||||||
|
|
||||||
|
namespace Timeline {
|
||||||
|
|
||||||
|
class TimelineOverviewRenderer : public TimelineAbstractRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TimelineOverviewRenderer(QQuickItem *parent = 0);
|
||||||
|
~TimelineOverviewRenderer();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData);
|
||||||
|
|
||||||
|
class TimelineOverviewRendererPrivate;
|
||||||
|
Q_DECLARE_PRIVATE(TimelineOverviewRenderer)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Timeline
|
||||||
|
|
||||||
|
QML_DECLARE_TYPE(Timeline::TimelineOverviewRenderer)
|
||||||
|
|
||||||
|
#endif // TIMELINEOVERVIEWRENDERER_H
|
||||||
@@ -1,5 +1,49 @@
|
|||||||
#ifndef TIMELINEOVERLAYRENDERER_P_H
|
/****************************************************************************
|
||||||
#define TIMELINEOVERLAYRENDERER_P_H
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
#endif // TIMELINEOVERLAYRENDERER_P_H
|
#ifndef TIMELINEOVERVIEWRENDERER_P_H
|
||||||
|
#define TIMELINEOVERVIEWRENDERER_P_H
|
||||||
|
|
||||||
|
#include "timelineoverviewrenderer.h"
|
||||||
|
#include "timelineabstractrenderer_p.h"
|
||||||
|
|
||||||
|
namespace Timeline {
|
||||||
|
|
||||||
|
class TimelineOverviewRenderer::TimelineOverviewRendererPrivate :
|
||||||
|
public TimelineAbstractRenderer::TimelineAbstractRendererPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TimelineRenderState *renderState;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Timeline
|
||||||
|
|
||||||
|
#endif // TIMELINEOVERVIEWRENDERER_P_H
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user