25 #include <QtConcurrentRun>
45 QPaintDevice *paintDevice = painter->device();
46 QString errMsg = QStringLiteral(
"pre-set DPI not equal to painter's DPI (%1 vs %2)" )
47 .arg( paintDevice->logicalDpiX() )
50 "Job::startRender()", errMsg.toLatin1().data() );
63 , mRenderSynchronously( false )
71 Q_ASSERT( !mFutureWatcher.isRunning() );
89 QgsDebugMsgLevel( QStringLiteral(
"Preparing list of layer jobs for rendering" ), 5 );
90 QElapsedTimer prepareTime;
95 mLabelingEngineV2.reset();
100 mLabelingEngineV2->setMapSettings(
mSettings );
104 mLayerJobs =
prepareJobs( mPainter, mLabelingEngineV2.get() );
105 mLabelJob =
prepareLabelingJob( mPainter, mLabelingEngineV2.get(), canUseLabelCache );
108 QgsDebugMsgLevel( QStringLiteral(
"Rendering prepared in (seconds): %1" ).arg( prepareTime.elapsed() / 1000.0 ), 4 );
110 if ( mRenderSynchronously )
121 connect( &mFutureWatcher, &QFutureWatcher<void>::finished,
this, &QgsMapRendererCustomPainterJob::futureFinished );
123 mFuture = QtConcurrent::run( staticRender,
this );
124 mFutureWatcher.setFuture( mFuture );
137 disconnect( &mFutureWatcher, &QFutureWatcher<void>::finished,
this, &QgsMapRendererCustomPainterJob::futureFinished );
143 mFutureWatcher.waitForFinished();
145 QgsDebugMsgLevel( QStringLiteral(
"QPAINER cancel waited %1 ms" ).arg( t.elapsed() / 1000.0 ), 5 );
156 QgsDebugMsg( QStringLiteral(
"QPAINTER not running!" ) );
160 mLabelJob.context.setRenderingStopped(
true );
161 for ( LayerRenderJobs::iterator it = mLayerJobs.begin(); it != mLayerJobs.end(); ++it )
163 it->context.setRenderingStopped(
true );
164 if ( it->renderer && it->renderer->feedback() )
165 it->renderer->feedback()->cancel();
174 disconnect( &mFutureWatcher, &QFutureWatcher<void>::finished,
this, &QgsMapRendererCustomPainterJob::futureFinished );
179 mFutureWatcher.waitForFinished();
181 QgsDebugMsgLevel( QStringLiteral(
"waitForFinished: %1 ms" ).arg( t.elapsed() / 1000.0 ), 4 );
193 return mLabelJob.cached;
198 if ( mLabelingEngineV2 )
199 return mLabelingEngineV2->takeResults();
208 connect( &mFutureWatcher, &QFutureWatcher<void>::finished, &loop, &QEventLoop::quit );
215 mRenderSynchronously =
true;
218 mRenderSynchronously =
false;
223 mRenderSynchronously =
true;
236 mRenderSynchronously =
false;
237 mPrepareOnly =
false;
241 void QgsMapRendererCustomPainterJob::futureFinished()
271 catch ( std::exception &e )
274 QgsDebugMsg(
"Caught unhandled std::exception: " + QString::fromLatin1( e.what() ) );
278 QgsDebugMsg( QStringLiteral(
"Caught unhandled unknown exception" ) );
282 void QgsMapRendererCustomPainterJob::doRender()
284 bool hasSecondPass = ! mSecondPassLayerJobs.isEmpty();
286 QElapsedTimer renderTime;
289 for ( LayerRenderJobs::iterator it = mLayerJobs.begin(); it != mLayerJobs.end(); ++it )
291 LayerRenderJob &job = *it;
293 if ( job.context.renderingStopped() )
296 if ( ! hasSecondPass && job.context.useAdvancedEffects() )
300 mPainter->setCompositionMode( job.blendMode );
305 QElapsedTimer layerTime;
311 job.imageInitialized =
true;
314 job.renderer->render();
316 job.renderingTime += layerTime.elapsed();
319 if ( ! hasSecondPass && job.img )
322 mPainter->setOpacity( job.opacity );
323 mPainter->drawImage( 0, 0, *job.img );
324 mPainter->setOpacity( 1.0 );
333 if ( !mLabelJob.cached )
335 QElapsedTimer labelTime;
341 mLabelJob.img->fill( 0 );
342 painter.begin( mLabelJob.img );
343 mLabelJob.context.setPainter( &painter );
344 drawLabeling( mLabelJob.context, mLabelingEngineV2.get(), &painter );
349 drawLabeling( mLabelJob.context, mLabelingEngineV2.get(), mPainter );
352 mLabelJob.complete =
true;
353 mLabelJob.renderingTime = labelTime.elapsed();
354 mLabelJob.participatingLayers = _qgis_listRawToQPointer( mLabelingEngineV2->participatingLayers() );
358 if ( ! hasSecondPass )
360 if ( mLabelJob.img && mLabelJob.complete )
362 mPainter->setCompositionMode( QPainter::CompositionMode_SourceOver );
363 mPainter->setOpacity( 1.0 );
364 mPainter->drawImage( 0, 0, *mLabelJob.img );
369 for ( LayerRenderJob &job : mSecondPassLayerJobs )
371 if ( job.context.renderingStopped() )
376 QElapsedTimer layerTime;
382 job.imageInitialized =
true;
385 job.renderer->render();
387 job.renderingTime += layerTime.elapsed();
395 mPainter->setCompositionMode( QPainter::CompositionMode_SourceOver );
396 mPainter->setOpacity( 1.0 );
397 mPainter->drawImage( 0, 0, finalImage );
400 QgsDebugMsgLevel( QStringLiteral(
"Rendering completed in (seconds): %1" ).arg( renderTime.elapsed() / 1000.0 ), 2 );