summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-26 11:16:12 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-27 08:05:12 +0300
commitf2a5c09144f17f3240ae6a7e7b48237f1b234d9b (patch)
tree28f40212cd228f66277e8db84885ddef0ebb6c5a /src/datavisualization/data
parentb776b6d3aa287b973c9346736badc6181e50cbc7 (diff)
Allow resetting with existing array for surface
Improves performance when doing stuff like resetting image data. Task-number: QTRD-2335 Change-Id: I9e8ce49fd520b67125305a7614afc550b2244169 Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Diffstat (limited to 'src/datavisualization/data')
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp27
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp52
-rw-r--r--src/datavisualization/data/qsurfacedataproxy_p.h6
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler.cpp43
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler_p.h1
5 files changed, 77 insertions, 52 deletions
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
index 25e2a4db..c0b0723c 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
@@ -206,28 +206,35 @@ void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve()
int widthBits = imageWidth * 4;
qreal height = 0;
- QSurfaceDataArray *dataArray = new QSurfaceDataArray;
- dataArray->reserve(imageHeight);
+ // Do not recreate array if dimensions have not changed
+ QSurfaceDataArray *dataArray = m_dataArray;
+ if (imageWidth != qptr()->columnCount() || imageHeight != dataArray->size()) {
+ dataArray = new QSurfaceDataArray;
+ dataArray->reserve(imageHeight);
+ for (int i = 0; i < imageHeight; i++) {
+ QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(imageWidth);
+ dataArray->append(newProxyRow);
+ }
+ }
+
if (heightImage.isGrayscale()) {
// Grayscale, it's enough to read Red byte
- for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) {
- QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth);
+ for (int i = 0; i < imageHeight; i++, bitCount -= widthBits) {
+ QSurfaceDataRow &newRow = *dataArray->at(i);
for (int j = 0; j < imageWidth; j++)
- (*newRow)[j] = qreal(bits[bitCount + (j * 4)]);
- *dataArray << newRow;
+ newRow[j] = qreal(bits[bitCount + (j * 4)]);
}
} else {
// Not grayscale, we'll need to calculate height from RGB
- for (int i = imageHeight; i > 0; i--, bitCount -= widthBits) {
- QSurfaceDataRow *newRow = new QSurfaceDataRow(imageWidth);
+ for (int i = 0; i < imageHeight; i++, bitCount -= widthBits) {
+ QSurfaceDataRow &newRow = *dataArray->at(i);
for (int j = 0; j < imageWidth; j++) {
int nextpixel = j * 4;
height = (qreal(bits[bitCount + nextpixel])
+ qreal(bits[1 + bitCount + nextpixel])
+ qreal(bits[2 + bitCount + nextpixel]));
- (*newRow)[j] = (height / 3.0);
+ newRow[j] = height / 3.0;
}
- *dataArray << newRow;
}
}
diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp
index 1a2e29ce..98998f10 100644
--- a/src/datavisualization/data/qsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qsurfacedataproxy.cpp
@@ -143,23 +143,29 @@ QSurfaceDataProxy::~QSurfaceDataProxy()
}
/*!
- * Clears the existing array and takes ownership of the \a newArray. Do not use \a newArray pointer
- * to further modify data after QSurfaceDataProxy assumes ownership of it, as such modifications will
- * not trigger proper signals.
- * Passing null array clears all data.
- * Row and column ranges are reset to defaults.
+ * Takes ownership of the \a newArray. Clears the existing array and if the \a newArray is
+ * different than the existing array. If it's the same array, this just triggers arrayReset()
+ * signal.
+ * Passing null array deletes the old array and creates a new empty array.
+ * All rows in \a newArray must be of same length.
+ * Row and column ranges are reset to defaults, unless \a newArray is the same as the old array.
+ * In that case, old row and column ranges are kept.
*/
void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray)
{
- if (dptr()->resetArray(newArray, defaultMinValue, defaultMaxValue, defaultMinValue, defaultMaxValue))
- emit arrayReset();
+ if (dptr()->m_dataArray != newArray) {
+ dptr()->resetArray(newArray, defaultMinValue, defaultMaxValue, defaultMinValue,
+ defaultMaxValue);
+ }
+ emit arrayReset();
}
/*!
- * Clears the existing array and takes ownership of the \a newArray. Do not use \a newArray pointer
- * to further modify data after QSurfaceDataProxy assumes ownership of it, as such modifications will
- * not trigger proper signals.
- * Passing null array clears all data.
+ * Takes ownership of the \a newArray. Clears the existing array and if the \a newArray is
+ * different than the existing array. If it's the same array, this just triggers arrayReset()
+ * signal and updates row/column values.
+ * Passing null array deletes the old array and creates a new empty array.
+ * All rows in \a newArray must be of same length.
* Row and column ranges are set to values defined by the rest of the parameters: \a minValueRows,
* \a maxValueRows, \a minValueColumns, and \a maxValueColumns.
*/
@@ -167,8 +173,8 @@ void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray, qreal minValueRo
qreal maxValueRows, qreal minValueColumns,
qreal maxValueColumns)
{
- if (dptr()->resetArray(newArray, minValueRows, maxValueRows, minValueColumns, maxValueColumns))
- emit arrayReset();
+ dptr()->resetArray(newArray, minValueRows, maxValueRows, minValueColumns, maxValueColumns);
+ emit arrayReset();
}
/*!
@@ -346,30 +352,20 @@ QSurfaceDataProxyPrivate::~QSurfaceDataProxyPrivate()
clearArray();
}
-bool QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray, qreal minValueRows,
+void QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray, qreal minValueRows,
qreal maxValueRows, qreal minValueColumns,
qreal maxValueColumns)
{
- if (!m_dataArray->size() && (!newArray || !newArray->size()))
- return false;
-
- clearArray();
+ if (!newArray)
+ newArray = new QSurfaceDataArray;
- if (newArray) {
- for (int i = 0; i < newArray->size(); i++) {
- Q_ASSERT_X((newArray->at(i) && newArray->at(i)->size() == newArray->at(0)->size()),
- __FUNCTION__,
- "All rows of QSurfaceDataArray mustn't be NULL and must be of equal size.");
- }
+ if (newArray != m_dataArray) {
+ clearArray();
m_dataArray = newArray;
- } else {
- m_dataArray = new QSurfaceDataArray;
}
setValueRangeRows(minValueRows, maxValueRows);
setValueRangeColumns(minValueColumns, maxValueColumns);
-
- return true;
}
void QSurfaceDataProxyPrivate::setValueRangeRows(qreal min, qreal max)
diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h
index 8a60e93d..a40e8d65 100644
--- a/src/datavisualization/data/qsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qsurfacedataproxy_p.h
@@ -43,7 +43,7 @@ public:
QSurfaceDataProxyPrivate(QSurfaceDataProxy *q);
virtual ~QSurfaceDataProxyPrivate();
- bool resetArray(QSurfaceDataArray *newArray, qreal minValueRows, qreal maxValueRows,
+ void resetArray(QSurfaceDataArray *newArray, qreal minValueRows, qreal maxValueRows,
qreal minValueColumns, qreal maxValueColumns);
void setValueRangeRows(qreal min, qreal max);
@@ -58,12 +58,14 @@ public:
void limitValues(QVector3D &minValues, QVector3D &maxValues);
+protected:
+ QSurfaceDataArray *m_dataArray;
+
private:
QSurfaceDataProxy *qptr();
void clearRow(int rowIndex);
void clearArray();
- QSurfaceDataArray *m_dataArray;
qreal m_minValueRows;
qreal m_maxValueRows;
qreal m_minValueColumns;
diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp
index bc85847c..d32b442b 100644
--- a/src/datavisualization/data/surfaceitemmodelhandler.cpp
+++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp
@@ -23,7 +23,8 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
SurfaceItemModelHandler::SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent)
: AbstractItemModelHandler(parent),
- m_proxy(proxy)
+ m_proxy(proxy),
+ m_proxyArray(0)
{
}
@@ -51,7 +52,6 @@ void SurfaceItemModelHandler::resolveModel()
float minColumnValue = 0.0f;
float maxColumnValue = 1.0f;
- QSurfaceDataArray *newProxyArray = new QSurfaceDataArray;
QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
// Default to display role if no mapping
@@ -60,11 +60,20 @@ void SurfaceItemModelHandler::resolveModel()
int columnCount = m_itemModel->columnCount();
if (mapping->useModelCategories()) {
+ // If dimensions have changed, recreate the array
+ if (!m_proxyArray || columnCount != m_proxy->columnCount()
+ || rowCount != m_proxyArray->size()) {
+ m_proxyArray = new QSurfaceDataArray;
+ m_proxyArray->reserve(rowCount);
+ for (int i = 0; i < rowCount; i++) {
+ QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(columnCount);
+ m_proxyArray->append(newProxyRow);
+ }
+ }
for (int i = 0; i < rowCount; i++) {
- QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(columnCount);
+ QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
for (int j = 0; j < columnCount; j++)
- (*newProxyRow)[j] = m_itemModel->index(i, j).data(valueRole).toReal();
- newProxyArray->append(newProxyRow);
+ newProxyRow[j] = m_itemModel->index(i, j).data(valueRole).toReal();
}
if (rowCount) {
minRowValue = m_itemModel->headerData(0, Qt::Vertical).toFloat();
@@ -118,12 +127,22 @@ void SurfaceItemModelHandler::resolveModel()
else
columnList = mapping->columnCategories();
- // Create new data array from itemValueMap
- foreach (QString rowKey, rowList) {
- QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(columnList.size());
- for (int i = 0; i < columnList.size(); i++)
- (*newProxyRow)[i] = itemValueMap[rowKey][columnList.at(i)];
- newProxyArray->append(newProxyRow);
+ // If dimensions have changed, recreate the array
+ if (!m_proxyArray || columnList.size() != m_proxy->columnCount()
+ || rowList.size() != m_proxyArray->size()) {
+ m_proxyArray = new QSurfaceDataArray;
+ m_proxyArray->reserve(rowList.size());
+ for (int i = 0; i < rowList.size(); i++) {
+ QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(columnList.size());
+ m_proxyArray->append(newProxyRow);
+ }
+ }
+ // Create data array from itemValueMap
+ for (int i = 0; i < rowList.size(); i++) {
+ QString rowKey = rowList.at(i);
+ QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
+ for (int j = 0; j < columnList.size(); j++)
+ newProxyRow[j] = itemValueMap[rowKey][columnList.at(j)];
}
// Use first and last roles converted to values for limits
@@ -137,7 +156,7 @@ void SurfaceItemModelHandler::resolveModel()
}
}
- m_proxy->resetArray(newProxyArray, minRowValue, maxRowValue, minColumnValue, maxColumnValue);
+ m_proxy->resetArray(m_proxyArray, minRowValue, maxRowValue, minColumnValue, maxColumnValue);
}
QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/surfaceitemmodelhandler_p.h b/src/datavisualization/data/surfaceitemmodelhandler_p.h
index 045ac379..bcf642c5 100644
--- a/src/datavisualization/data/surfaceitemmodelhandler_p.h
+++ b/src/datavisualization/data/surfaceitemmodelhandler_p.h
@@ -45,6 +45,7 @@ protected:
void virtual resolveModel();
QItemModelSurfaceDataProxy *m_proxy; // Not owned
+ QSurfaceDataArray *m_proxyArray; // Not owned
};
QT_DATAVISUALIZATION_END_NAMESPACE