Skip to content

Commit

Permalink
don't access the dem data provider from a different thread
Browse files Browse the repository at this point in the history
  • Loading branch information
uclaros authored and nyalldawson committed Jan 23, 2023
1 parent d086604 commit 63996b2
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 13 deletions.
19 changes: 9 additions & 10 deletions src/3d/terrain/qgsdemterraintileloader_p.cpp
Expand Up @@ -152,8 +152,7 @@ void QgsDemTerrainTileLoader::onHeightMapReady( int jobId, const QByteArray &hei
#include "qgsterraindownloader.h"

QgsDemHeightMapGenerator::QgsDemHeightMapGenerator( QgsRasterLayer *dtm, const QgsTilingScheme &tilingScheme, int resolution, const QgsCoordinateTransformContext &transformContext )
: mDtm( dtm )
, mDtmExtent( dtm ? dtm->extent() : QgsRectangle() )
: mDtmExtent( dtm ? dtm->extent() : QgsRectangle() )
, mClonedProvider( dtm ? qgis::down_cast<QgsRasterDataProvider *>( dtm->dataProvider()->clone() ) : nullptr )
, mTilingScheme( tilingScheme )
, mResolution( resolution )
Expand Down Expand Up @@ -219,8 +218,7 @@ static QByteArray _readDtmData( QgsRasterDataProvider *provider, const QgsRectan
}
}

provider->moveToThread( nullptr );

delete provider;
return data;
}

Expand Down Expand Up @@ -249,11 +247,12 @@ int QgsDemHeightMapGenerator::render( const QgsChunkNodeId &nodeId )
QFutureWatcher<QByteArray> *fw = new QFutureWatcher<QByteArray>( nullptr );
connect( fw, &QFutureWatcher<QByteArray>::finished, this, &QgsDemHeightMapGenerator::onFutureFinished );
connect( fw, &QFutureWatcher<QByteArray>::finished, fw, &QObject::deleteLater );
// make a clone of the data provider so it is safe to use in worker thread
if ( mDtm )
if ( mClonedProvider )
{
mClonedProvider->moveToThread( nullptr );
jd.future = QtConcurrent::run( _readDtmData, mClonedProvider, extent, mResolution, mTilingScheme.crs(), mTilingScheme.fullExtent() );
// make a clone of the data provider so it is safe to use in worker thread
std::unique_ptr< QgsRasterDataProvider > clonedProviderClone( mClonedProvider->clone() );
clonedProviderClone->moveToThread( nullptr );
jd.future = QtConcurrent::run( _readDtmData, clonedProviderClone.release(), extent, mResolution, mTilingScheme.crs(), mTilingScheme.fullExtent() );
}
else
{
Expand Down Expand Up @@ -299,7 +298,7 @@ void QgsDemHeightMapGenerator::lazyLoadDtmCoarseData( int res, const QgsRectangl
QMutexLocker locker( &mLazyLoadDtmCoarseDataMutex );
if ( mDtmCoarseData.isEmpty() )
{
std::unique_ptr< QgsRasterBlock > block( mDtm->dataProvider()->block( 1, rect, res, res ) );
std::unique_ptr< QgsRasterBlock > block( mClonedProvider->block( 1, rect, res, res ) );
block->convert( Qgis::DataType::Float32 );
mDtmCoarseData = block->data();
mDtmCoarseData.detach(); // make a deep copy
Expand All @@ -308,7 +307,7 @@ void QgsDemHeightMapGenerator::lazyLoadDtmCoarseData( int res, const QgsRectangl

float QgsDemHeightMapGenerator::heightAt( double x, double y )
{
if ( !mDtm )
if ( !mClonedProvider )
return 0; // TODO: calculate heights for online DTM

// TODO: this is quite a primitive implementation: better to use heightmaps currently in use
Expand Down
3 changes: 0 additions & 3 deletions src/3d/terrain/qgsdemterraintileloader_p.h
Expand Up @@ -110,9 +110,6 @@ class QgsDemHeightMapGenerator : public QObject
void onFutureFinished();

private:
//! raster used to build terrain
QgsRasterLayer *mDtm = nullptr;

//! dtm raster layer's extent in layer crs
const QgsRectangle mDtmExtent;

Expand Down

0 comments on commit 63996b2

Please sign in to comment.