diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-26 11:16:12 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-09-27 08:05:12 +0300 |
commit | f2a5c09144f17f3240ae6a7e7b48237f1b234d9b (patch) | |
tree | 28f40212cd228f66277e8db84885ddef0ebb6c5a /src/datavisualization/data | |
parent | b776b6d3aa287b973c9346736badc6181e50cbc7 (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')
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 |