25 #include <QtConcurrentRun>
43 #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
48 QPaintDevice *paintDevice = painter->device();
49 QString errMsg = QStringLiteral(
"pre-set DPI not equal to painter's DPI (%1 vs %2)" )
50 .arg( paintDevice->logicalDpiX() )
53 "Job::startRender()", errMsg.toLatin1().data() );
66 , mRenderSynchronously( false )
74 Q_ASSERT( !mFutureWatcher.isRunning() );
92 QgsDebugMsgLevel( QStringLiteral(
"Preparing list of layer jobs for rendering" ), 5 );
93 QElapsedTimer prepareTime;
98 mLabelingEngineV2.reset();
103 mLabelingEngineV2->setMapSettings(
mSettings );
107 mLayerJobs =
prepareJobs( mPainter, mLabelingEngineV2.get() );
108 mLabelJob =
prepareLabelingJob( mPainter, mLabelingEngineV2.get(), canUseLabelCache );
111 QgsDebugMsgLevel( QStringLiteral(
"Rendering prepared in (seconds): %1" ).arg( prepareTime.elapsed() / 1000.0 ), 4 );
113 if ( mRenderSynchronously )
124 connect( &mFutureWatcher, &QFutureWatcher<void>::finished,
this, &QgsMapRendererCustomPainterJob::futureFinished );
126 mFuture = QtConcurrent::run( staticRender,
this );
127 mFutureWatcher.setFuture( mFuture );
140 disconnect( &mFutureWatcher, &QFutureWatcher<void>::finished,
this, &QgsMapRendererCustomPainterJob::futureFinished );
146 mFutureWatcher.waitForFinished();
148 QgsDebugMsgLevel( QStringLiteral(
"QPAINER cancel waited %1 ms" ).arg( t.elapsed() / 1000.0 ), 5 );
159 QgsDebugMsg( QStringLiteral(
"QPAINTER not running!" ) );
163 mLabelJob.context.setRenderingStopped(
true );
164 for ( LayerRenderJobs::iterator it = mLayerJobs.begin(); it != mLayerJobs.end(); ++it )
166 it->context.setRenderingStopped(
true );
167 if ( it->renderer && it->renderer->feedback() )
168 it->renderer->feedback()->cancel();
177 disconnect( &mFutureWatcher, &QFutureWatcher<void>::finished,
this, &QgsMapRendererCustomPainterJob::futureFinished );
182 mFutureWatcher.waitForFinished();
184 QgsDebugMsgLevel( QStringLiteral(
"waitForFinished: %1 ms" ).arg( t.elapsed() / 1000.0 ), 4 );
196 return mLabelJob.cached;
201 if ( mLabelingEngineV2 )
202 return mLabelingEngineV2->takeResults();
211 connect( &mFutureWatcher, &QFutureWatcher<void>::finished, &loop, &QEventLoop::quit );
218 mRenderSynchronously =
true;
221 mRenderSynchronously =
false;
226 mRenderSynchronously =
true;
239 mRenderSynchronously =
false;
240 mPrepareOnly =
false;
244 void QgsMapRendererCustomPainterJob::futureFinished()
274 catch ( std::exception &e )
277 QgsDebugMsg(
"Caught unhandled std::exception: " + QString::fromLatin1( e.what() ) );
281 QgsDebugMsg( QStringLiteral(
"Caught unhandled unknown exception" ) );
285 void QgsMapRendererCustomPainterJob::doRender()
287 bool hasSecondPass = ! mSecondPassLayerJobs.isEmpty();
289 QElapsedTimer renderTime;
292 for ( LayerRenderJobs::iterator it = mLayerJobs.begin(); it != mLayerJobs.end(); ++it )
294 LayerRenderJob &job = *it;
296 if ( job.context.renderingStopped() )
299 if ( ! hasSecondPass && job.context.useAdvancedEffects() )
303 mPainter->setCompositionMode( job.blendMode );
308 QElapsedTimer layerTime;
314 job.imageInitialized =
true;
317 job.renderer->render();
319 job.renderingTime += layerTime.elapsed();
322 if ( ! hasSecondPass && job.img )
325 mPainter->setOpacity( job.opacity );
326 mPainter->drawImage( 0, 0, *job.img );
327 mPainter->setOpacity( 1.0 );
336 if ( !mLabelJob.cached )
338 QElapsedTimer labelTime;
344 mLabelJob.img->fill( 0 );
345 painter.begin( mLabelJob.img );
346 mLabelJob.context.setPainter( &painter );
347 drawLabeling( mLabelJob.context, mLabelingEngineV2.get(), &painter );
352 drawLabeling( mLabelJob.context, mLabelingEngineV2.get(), mPainter );
355 mLabelJob.complete =
true;
356 mLabelJob.renderingTime = labelTime.elapsed();
357 mLabelJob.participatingLayers = _qgis_listRawToQPointer( mLabelingEngineV2->participatingLayers() );
361 if ( ! hasSecondPass )
363 if ( mLabelJob.img && mLabelJob.complete )
365 mPainter->setCompositionMode( QPainter::CompositionMode_SourceOver );
366 mPainter->setOpacity( 1.0 );
367 mPainter->drawImage( 0, 0, *mLabelJob.img );
372 for ( LayerRenderJob &job : mSecondPassLayerJobs )
374 if ( job.context.renderingStopped() )
379 QElapsedTimer layerTime;
385 job.imageInitialized =
true;
388 job.renderer->render();
390 job.renderingTime += layerTime.elapsed();
398 mPainter->setCompositionMode( QPainter::CompositionMode_SourceOver );
399 mPainter->setOpacity( 1.0 );
400 mPainter->drawImage( 0, 0, finalImage );
403 QgsDebugMsgLevel( QStringLiteral(
"Rendering completed in (seconds): %1" ).arg( renderTime.elapsed() / 1000.0 ), 2 );