summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-04-30 15:36:19 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-05-02 10:53:05 +0300
commit13d1117087e66c77d2eea2f0a046fc556c19cb3c (patch)
treef003ec51145278cea0fd2d123da6c0478c961297 /src
parent44b410f080c4820cea682c4d1278152d2767595c (diff)
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 <titta.heikkala@digia.com> Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp4
-rw-r--r--src/datavisualization/engine/bars3drenderer_p.h2
-rw-r--r--src/datavisualization/engine/scatter3dcontroller.cpp42
-rw-r--r--src/datavisualization/engine/scatter3dcontroller_p.h10
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp67
-rw-r--r--src/datavisualization/engine/scatter3drenderer_p.h2
6 files changed, 91 insertions, 36 deletions
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index ec1f0c7e..ab7bb4ca 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -342,7 +342,7 @@ void Bars3DRenderer::updateRows(const QVector<Bars3DController::ChangeRow> &rows
}
}
-void Bars3DRenderer::updateItems(const QVector<Bars3DController::ChangeItem> &points)
+void Bars3DRenderer::updateItems(const QVector<Bars3DController::ChangeItem> &items)
{
int minRow = m_axisCacheZ.min();
int maxRow = m_axisCacheZ.max();
@@ -352,7 +352,7 @@ void Bars3DRenderer::updateItems(const QVector<Bars3DController::ChangeItem> &po
const QBar3DSeries *prevSeries = 0;
const QBarDataArray *dataArray = 0;
- foreach (Bars3DController::ChangeItem item, points) {
+ foreach (Bars3DController::ChangeItem item, items) {
const int row = item.point.x();
const int col = item.point.y();
if (row < minRow || row > maxRow || col < minCol || col > maxCol)
diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h
index ddea546e..8e39ee11 100644
--- a/src/datavisualization/engine/bars3drenderer_p.h
+++ b/src/datavisualization/engine/bars3drenderer_p.h
@@ -118,7 +118,7 @@ public:
void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
void updateRows(const QVector<Bars3DController::ChangeRow> &rows);
- void updateItems(const QVector<Bars3DController::ChangeItem> &points);
+ void updateItems(const QVector<Bars3DController::ChangeItem> &items);
void updateScene(Q3DScene *scene);
void render(GLuint defaultFboHandle = 0);
diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp
index 05c0efe7..2d38a4a7 100644
--- a/src/datavisualization/engine/scatter3dcontroller.cpp
+++ b/src/datavisualization/engine/scatter3dcontroller.cpp
@@ -71,6 +71,12 @@ void Scatter3DController::synchDataToRenderer()
Abstract3DController::synchDataToRenderer();
// Notify changes to renderer
+ if (m_changeTracker.itemChanged) {
+ m_renderer->updateItems(m_changedItems);
+ m_changeTracker.itemChanged = false;
+ m_changedItems.clear();
+ }
+
if (m_changeTracker.selectedItemChanged) {
m_renderer->updateSelectedItem(m_selectedItem, m_selectedItemSeries);
m_changeTracker.selectedItemChanged = false;
@@ -144,17 +150,35 @@ void Scatter3DController::handleItemsAdded(int startIndex, int count)
void Scatter3DController::handleItemsChanged(int startIndex, int count)
{
- Q_UNUSED(startIndex)
- Q_UNUSED(count)
QScatter3DSeries *series = static_cast<QScatterDataProxy *>(sender())->series();
- if (series->isVisible()) {
- adjustAxisRanges();
- m_isDataDirty = true;
- series->d_ptr->markItemLabelDirty();
+ int oldChangeCount = m_changedItems.size();
+ if (!oldChangeCount)
+ m_changedItems.reserve(count);
+
+ for (int i = 0; i < count; i++) {
+ bool newItem = true;
+ int candidate = startIndex + i;
+ for (int j = 0; j < oldChangeCount; j++) {
+ const ChangeItem &oldChangeItem = m_changedItems.at(j);
+ if (oldChangeItem.index == candidate && series == oldChangeItem.series) {
+ newItem = false;
+ break;
+ }
+ }
+ if (newItem) {
+ ChangeItem newChangeItem = {series, candidate};
+ m_changedItems.append(newChangeItem);
+ if (series == m_selectedItemSeries && m_selectedItem == candidate)
+ series->d_ptr->markItemLabelDirty();
+ }
+ }
+
+ if (count) {
+ m_changeTracker.itemChanged = true;
+ if (series->isVisible())
+ adjustAxisRanges();
+ emitNeedRender();
}
- if (!m_changedSeriesList.contains(series))
- m_changedSeriesList.append(series);
- emitNeedRender();
}
void Scatter3DController::handleItemsRemoved(int startIndex, int count)
diff --git a/src/datavisualization/engine/scatter3dcontroller_p.h b/src/datavisualization/engine/scatter3dcontroller_p.h
index 1194bc3a..db5a95f5 100644
--- a/src/datavisualization/engine/scatter3dcontroller_p.h
+++ b/src/datavisualization/engine/scatter3dcontroller_p.h
@@ -40,9 +40,11 @@ class QScatter3DSeries;
struct Scatter3DChangeBitField {
bool selectedItemChanged : 1;
+ bool itemChanged : 1;
Scatter3DChangeBitField() :
- selectedItemChanged(true)
+ selectedItemChanged(true),
+ itemChanged(false)
{
}
};
@@ -51,8 +53,14 @@ class QT_DATAVISUALIZATION_EXPORT Scatter3DController : public Abstract3DControl
{
Q_OBJECT
+public:
+ struct ChangeItem {
+ QScatter3DSeries *series;
+ int index;
+ };
private:
Scatter3DChangeBitField m_changeTracker;
+ QVector<ChangeItem> m_changedItems;
// Rendering
Scatter3DRenderer *m_renderer;
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index 3f91e9c3..c1705179 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -165,12 +165,6 @@ void Scatter3DRenderer::initializeOpenGL()
void Scatter3DRenderer::updateData()
{
calculateSceneScalingFactors();
- float minX = float(m_axisCacheX.min());
- float maxX = float(m_axisCacheX.max());
- float minY = float(m_axisCacheY.min());
- float maxY = float(m_axisCacheY.max());
- float minZ = float(m_axisCacheZ.min());
- float maxZ = float(m_axisCacheZ.max());
int totalDataSize = 0;
foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
@@ -185,23 +179,8 @@ void Scatter3DRenderer::updateData()
if (dataSize != renderArray.size())
renderArray.resize(dataSize);
- for (int i = 0; i < dataSize; i++) {
- QVector3D dotPos = dataArray.at(i).position();
- ScatterRenderItem &renderItem = renderArray[i];
- if ((dotPos.x() >= minX && dotPos.x() <= maxX )
- && (dotPos.y() >= minY && dotPos.y() <= maxY)
- && (dotPos.z() >= minZ && dotPos.z() <= maxZ)) {
- renderItem.setPosition(dotPos);
- renderItem.setVisible(true);
- if (!dataArray.at(i).rotation().isIdentity())
- renderItem.setRotation(dataArray.at(i).rotation().normalized());
- else
- renderItem.setRotation(identityQuaternion);
- calculateTranslation(renderItem);
- } else {
- renderItem.setVisible(false);
- }
- }
+ for (int i = 0; i < dataSize; i++)
+ updateRenderItem(dataArray.at(i), renderArray[i]);
cache->setDataDirty(false);
}
}
@@ -272,6 +251,30 @@ SeriesRenderCache *Scatter3DRenderer::createNewCache(QAbstract3DSeries *series)
return new ScatterSeriesRenderCache(series, this);
}
+void Scatter3DRenderer::updateItems(const QVector<Scatter3DController::ChangeItem> &items)
+{
+ ScatterSeriesRenderCache *cache = 0;
+ const QScatter3DSeries *prevSeries = 0;
+ const QScatterDataArray *dataArray = 0;
+
+ foreach (Scatter3DController::ChangeItem item, items) {
+ QScatter3DSeries *currentSeries = item.series;
+ if (currentSeries != prevSeries) {
+ cache = static_cast<ScatterSeriesRenderCache *>(m_renderCacheList.value(currentSeries));
+ prevSeries = currentSeries;
+ dataArray = item.series->dataProxy()->array();
+ // Invisible series render caches are not updated, but instead just marked dirty, so that
+ // they can be completely recalculated when they are turned visible.
+ if (!cache->isVisible() && !cache->dataDirty())
+ cache->setDataDirty(true);
+ }
+ if (cache->isVisible()) {
+ const int index = item.index;
+ updateRenderItem(dataArray->at(index), cache->renderArray()[index]);
+ }
+ }
+}
+
void Scatter3DRenderer::updateScene(Q3DScene *scene)
{
scene->activeCamera()->d_ptr->setMinYRotation(-90.0f);
@@ -1802,6 +1805,24 @@ void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector4D &color,
series = 0;
}
+void Scatter3DRenderer::updateRenderItem(const QScatterDataItem &dataItem, ScatterRenderItem &renderItem)
+{
+ QVector3D dotPos = dataItem.position();
+ if ((dotPos.x() >= m_axisCacheX.min() && dotPos.x() <= m_axisCacheX.max() )
+ && (dotPos.y() >= m_axisCacheY.min() && dotPos.y() <= m_axisCacheY.max())
+ && (dotPos.z() >= m_axisCacheZ.min() && dotPos.z() <= m_axisCacheZ.max())) {
+ renderItem.setPosition(dotPos);
+ renderItem.setVisible(true);
+ if (!dataItem.rotation().isIdentity())
+ renderItem.setRotation(dataItem.rotation().normalized());
+ else
+ renderItem.setRotation(identityQuaternion);
+ calculateTranslation(renderItem);
+ } else {
+ renderItem.setVisible(false);
+ }
+}
+
QVector3D Scatter3DRenderer::convertPositionToTranslation(const QVector3D &position) {
float xTrans = m_axisCacheX.positionAt(position.x());
float yTrans = m_axisCacheY.positionAt(position.y());
diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h
index 172d0c46..09b8dace 100644
--- a/src/datavisualization/engine/scatter3drenderer_p.h
+++ b/src/datavisualization/engine/scatter3drenderer_p.h
@@ -105,6 +105,7 @@ public:
void updateData();
void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
+ void updateItems(const QVector<Scatter3DController::ChangeItem> &items);
void updateScene(Q3DScene *scene);
QVector3D convertPositionToTranslation(const QVector3D &position);
@@ -154,6 +155,7 @@ public slots:
private:
void selectionColorToSeriesAndIndex(const QVector4D &color, int &index,
QAbstract3DSeries *&series);
+ inline void updateRenderItem(const QScatterDataItem &dataItem, ScatterRenderItem &renderItem);
};
QT_END_NAMESPACE_DATAVISUALIZATION