From 13d1117087e66c77d2eea2f0a046fc556c19cb3c Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 30 Apr 2014 15:36:19 +0300 Subject: Scatter data changing optimization. No longer reset the entire render item array if single item changes, significantly speeding up this operation. Task-number: QTRD-2190 Change-Id: Ia3de833b761dc6f24acff581ad79668f51c3e9c5 Reviewed-by: Titta Heikkala Reviewed-by: Mika Salmela --- tests/scattertest/main.cpp | 20 +++- tests/scattertest/scatterchart.cpp | 197 ++++++++++++++++++++++++++++++++++++- tests/scattertest/scatterchart.h | 6 ++ 3 files changed, 220 insertions(+), 3 deletions(-) (limited to 'tests/scattertest') diff --git a/tests/scattertest/main.cpp b/tests/scattertest/main.cpp index 78bab934..82d025aa 100644 --- a/tests/scattertest/main.cpp +++ b/tests/scattertest/main.cpp @@ -123,6 +123,9 @@ int main(int argc, char **argv) QPushButton *massiveDataTestButton = new QPushButton(widget); massiveDataTestButton->setText(QStringLiteral("Massive data test")); + QPushButton *testItemChangesButton = new QPushButton(widget); + testItemChangesButton->setText(QStringLiteral("Test Item changing")); + QLinearGradient grBtoY(0, 0, 100, 0); grBtoY.setColorAt(1.0, Qt::black); grBtoY.setColorAt(0.67, Qt::blue); @@ -137,6 +140,12 @@ int main(int argc, char **argv) gradientBtoYPB->setIcon(QIcon(pm)); gradientBtoYPB->setIconSize(QSize(100, 24)); + QLabel *fpsLabel = new QLabel(QStringLiteral("")); + + QCheckBox *fpsCheckBox = new QCheckBox(widget); + fpsCheckBox->setText(QStringLiteral("Measure Fps")); + fpsCheckBox->setChecked(false); + QCheckBox *backgroundCheckBox = new QCheckBox(widget); backgroundCheckBox->setText(QStringLiteral("Show background")); backgroundCheckBox->setChecked(true); @@ -232,9 +241,12 @@ int main(int argc, char **argv) vLayout->addWidget(toggleSeriesVisibilityButton, 0, Qt::AlignTop); vLayout->addWidget(changeSeriesNameButton, 0, Qt::AlignTop); vLayout->addWidget(startTimerButton, 0, Qt::AlignTop); - vLayout->addWidget(massiveDataTestButton, 1, Qt::AlignTop); + vLayout->addWidget(massiveDataTestButton, 0, Qt::AlignTop); + vLayout->addWidget(testItemChangesButton, 1, Qt::AlignTop); vLayout2->addWidget(gradientBtoYPB, 0, Qt::AlignTop); + vLayout2->addWidget(fpsLabel, 0, Qt::AlignTop); + vLayout2->addWidget(fpsCheckBox, 0, Qt::AlignTop); vLayout2->addWidget(backgroundCheckBox); vLayout2->addWidget(gridCheckBox); vLayout2->addWidget(new QLabel(QStringLiteral("Adjust shadow quality"))); @@ -302,6 +314,8 @@ int main(int argc, char **argv) &ScatterDataModifier::startStopTimer); QObject::connect(massiveDataTestButton, &QPushButton::clicked, modifier, &ScatterDataModifier::massiveDataTest); + QObject::connect(testItemChangesButton, &QPushButton::clicked, modifier, + &ScatterDataModifier::testItemChanges); QObject::connect(gradientBtoYPB, &QPushButton::clicked, modifier, &ScatterDataModifier::setGradient); QObject::connect(themeButton, &QPushButton::clicked, modifier, @@ -316,6 +330,8 @@ int main(int argc, char **argv) QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier, &ScatterDataModifier::changeFont); + QObject::connect(fpsCheckBox, &QCheckBox::stateChanged, modifier, + &ScatterDataModifier::setFpsMeasurement); QObject::connect(backgroundCheckBox, &QCheckBox::stateChanged, modifier, &ScatterDataModifier::setBackgroundEnabled); QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier, @@ -335,6 +351,8 @@ int main(int argc, char **argv) &ScatterDataModifier::setMaxZ); + modifier->setFpsLabel(fpsLabel); + modifier->start(); return app.exec(); diff --git a/tests/scattertest/scatterchart.cpp b/tests/scattertest/scatterchart.cpp index c9404736..13a0f040 100644 --- a/tests/scattertest/scatterchart.cpp +++ b/tests/scattertest/scatterchart.cpp @@ -134,7 +134,6 @@ void ScatterDataModifier::massiveDataTest() xAxis->setSegmentCount(1); yAxis->setSegmentCount(1); zAxis->setSegmentCount(1); - m_chart->setMeasureFps(true); m_chart->setAxisX(xAxis); m_chart->setAxisY(yAxis); m_chart->setAxisZ(zAxis); @@ -231,6 +230,187 @@ void ScatterDataModifier::massiveTestAppendAndScroll() m_chart->axisZ()->setRange(min, max); } +void ScatterDataModifier::setFpsMeasurement(bool enable) +{ + m_chart->setMeasureFps(enable); +} + +void ScatterDataModifier::testItemChanges() +{ + static int counter = 0; + const int rowCount = 12; + const int colCount = 10; + static QScatter3DSeries *series0 = 0; + static QScatter3DSeries *series1 = 0; + static QScatter3DSeries *series2 = 0; + + switch (counter) { + case 0: { + qDebug() << __FUNCTION__ << counter << "Setup test"; + foreach (QScatter3DSeries *series, m_chart->seriesList()) + m_chart->removeSeries(series); + foreach (QValue3DAxis *axis, m_chart->axes()) + m_chart->releaseAxis(axis); + delete series0; + delete series1; + delete series2; + series0 = new QScatter3DSeries; + series1 = new QScatter3DSeries; + series2 = new QScatter3DSeries; + populateFlatSeries(series0, rowCount, colCount, 10.0f); + populateFlatSeries(series1, rowCount, colCount, 30.0f); + populateFlatSeries(series2, rowCount, colCount, 50.0f); + m_chart->axisX()->setRange(3.0f, 6.0f); + m_chart->axisY()->setRange(0.0f, 100.0f); + m_chart->axisZ()->setRange(4.0f, 8.0f); + m_chart->addSeries(series0); + m_chart->addSeries(series1); + m_chart->addSeries(series2); + } + break; + case 1: { + qDebug() << __FUNCTION__ << counter << "Change single item, unselected"; + int itemIndex = 3 * colCount + 5; + QScatterDataItem item = *series0->dataProxy()->itemAt(itemIndex); + item.setY(75.0f); + series0->dataProxy()->setItem(itemIndex, item); + } + break; + case 2: { + qDebug() << __FUNCTION__ << counter << "Change single item, selected"; + int itemIndex = 4 * colCount + 4; + series1->setSelectedItem(itemIndex); + QScatterDataItem item = *series1->dataProxy()->itemAt(itemIndex); + item.setY(75.0f); + series1->dataProxy()->setItem(itemIndex, item); + } + break; + case 3: { + qDebug() << __FUNCTION__ << counter << "Change item outside visible area"; + int itemIndex = 2; + QScatterDataItem item = *series1->dataProxy()->itemAt(itemIndex); + item.setY(75.0f); + series1->dataProxy()->setItem(itemIndex, item); + } + break; + case 4: { + qDebug() << __FUNCTION__ << counter << "Change single item from two series, unselected"; + int itemIndex = 4 * colCount + 6; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex); + item0.setY(65.0f); + item1.setY(85.0f); + series0->dataProxy()->setItem(itemIndex, item0); + series1->dataProxy()->setItem(itemIndex, item1); + } + break; + case 5: { + qDebug() << __FUNCTION__ << counter << "Change single item from two series, one selected"; + int itemIndex0 = 5 * colCount + 5; + int itemIndex1 = 4 * colCount + 4; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex0); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex1); + item0.setY(65.0f); + item1.setY(85.0f); + series0->dataProxy()->setItem(itemIndex0, item0); + series1->dataProxy()->setItem(itemIndex1, item1); + } + break; + case 6: { + qDebug() << __FUNCTION__ << counter << "Change single item from two series, one outside range"; + int itemIndex0 = 6 * colCount + 6; + int itemIndex1 = 9 * colCount + 2; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex0); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex1); + item0.setY(65.0f); + item1.setY(85.0f); + series0->dataProxy()->setItem(itemIndex0, item0); + series1->dataProxy()->setItem(itemIndex1, item1); + } + break; + case 7: { + qDebug() << __FUNCTION__ << counter << "Change single item from two series, both outside range"; + int itemIndex0 = 1 * colCount + 3; + int itemIndex1 = 9 * colCount + 2; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex0); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex1); + item0.setY(65.0f); + item1.setY(85.0f); + series0->dataProxy()->setItem(itemIndex0, item0); + series1->dataProxy()->setItem(itemIndex1, item1); + } + break; + case 8: { + qDebug() << __FUNCTION__ << counter << "Change item to same value as previously"; + int itemIndex0 = 5 * colCount + 7; + int itemIndex1 = 4 * colCount + 7; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex0); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex1); + series0->dataProxy()->setItem(itemIndex0, item0); + series1->dataProxy()->setItem(itemIndex1, item1); + } + break; + case 9: { + qDebug() << __FUNCTION__ << counter << "Change 3 items on each series"; + int itemIndex0 = 5 * colCount + 6; + int itemIndex1 = 4 * colCount + 6; + QScatterDataItem item00 = *series0->dataProxy()->itemAt(itemIndex0); + QScatterDataItem item01 = *series0->dataProxy()->itemAt(itemIndex0 + 1); + QScatterDataItem item02 = *series0->dataProxy()->itemAt(itemIndex0 + 2); + QScatterDataItem item10 = *series1->dataProxy()->itemAt(itemIndex1); + QScatterDataItem item11 = *series1->dataProxy()->itemAt(itemIndex1 + 1); + QScatterDataItem item12 = *series1->dataProxy()->itemAt(itemIndex1 + 2); + item00.setY(65.0f); + item01.setY(70.0f); + item02.setY(75.0f); + item10.setY(80.0f); + item11.setY(85.0f); + item12.setY(90.0f); + series0->dataProxy()->setItem(itemIndex0, item00); + series0->dataProxy()->setItem(itemIndex0 + 1, item01); + series0->dataProxy()->setItem(itemIndex0 + 2, item02); + series1->dataProxy()->setItem(itemIndex1, item10); + series1->dataProxy()->setItem(itemIndex1 + 1, item11); + series1->dataProxy()->setItem(itemIndex1 + 2, item12); + } + break; + case 10: { + qDebug() << __FUNCTION__ << counter << "Level the field single item at a time"; + QScatterDataItem item; + for (int i = 0; i < rowCount; i++) { + for (int j = 0; j < colCount; j++) { + int itemIndex = i * colCount + j; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex); + QScatterDataItem item2 = *series2->dataProxy()->itemAt(itemIndex); + item0.setY(10.0f); + item1.setY(15.0f); + item2.setY(20.0f); + series0->dataProxy()->setItem(itemIndex, item0); + series1->dataProxy()->setItem(itemIndex, item1); + series2->dataProxy()->setItem(itemIndex, item2); + } + } + } + break; + case 11: { + qDebug() << __FUNCTION__ << counter << "Change same items multiple times"; + int itemIndex0 = 6 * colCount + 6; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex0); + item0.setY(90.0f); + series0->dataProxy()->setItem(itemIndex0, item0); + series0->dataProxy()->setItem(itemIndex0, item0); + series0->dataProxy()->setItem(itemIndex0, item0); + series0->dataProxy()->setItem(itemIndex0, item0); + } + break; + default: + qDebug() << __FUNCTION__ << "Resetting test"; + counter = -1; + } + counter++; +} + void ScatterDataModifier::addData() { // Add labels @@ -673,7 +853,8 @@ void ScatterDataModifier::handleAxisZChanged(QValue3DAxis *axis) void ScatterDataModifier::handleFpsChange(qreal fps) { - qDebug() << "FPS:" << fps; + static const QString fpsPrefix(QStringLiteral("FPS: ")); + m_fpsLabel->setText(fpsPrefix + QString::number(qRound(fps))); } void ScatterDataModifier::changeShadowQuality(int quality) @@ -757,3 +938,15 @@ QScatter3DSeries *ScatterDataModifier::createAndAddSeries() return series; } + +void ScatterDataModifier::populateFlatSeries(QScatter3DSeries *series, int rows, int columns, + float value) +{ + QScatterDataArray *dataArray = new QScatterDataArray; + dataArray->resize(rows * columns); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) + (*dataArray)[i * columns + j].setPosition(QVector3D(float(i), value, float(j))); + } + series->dataProxy()->resetArray(dataArray); +} diff --git a/tests/scattertest/scatterchart.h b/tests/scattertest/scatterchart.h index 66f69625..f239cb73 100644 --- a/tests/scattertest/scatterchart.h +++ b/tests/scattertest/scatterchart.h @@ -25,6 +25,7 @@ #include #include #include +#include using namespace QtDataVisualization; @@ -55,6 +56,9 @@ public: void massiveDataTest(); void massiveTestScroll(); void massiveTestAppendAndScroll(); + void setFpsMeasurement(bool enable); + void setFpsLabel(QLabel *fpsLabel) { m_fpsLabel = fpsLabel; } + void testItemChanges(); public slots: void changeShadowQuality(int quality); @@ -91,6 +95,7 @@ signals: private: QVector3D randVector(); QScatter3DSeries *createAndAddSeries(); + void populateFlatSeries(QScatter3DSeries *series, int rows, int columns, float value); Q3DScatter *m_chart; int m_fontSize; @@ -99,6 +104,7 @@ private: int m_selectedItem; QScatter3DSeries *m_targetSeries; QScatterDataArray m_massiveTestCacheArray; + QLabel *m_fpsLabel; }; #endif -- cgit v1.2.3