Skip to content

Commit 4493f51

Browse files
committed
Draw labeling also in parallel map renderer job
1 parent b99e93c commit 4493f51

4 files changed

+165
-52
lines changed

src/core/qgsmaprendererjob.cpp

+144-45
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ void QgsMapRendererCustomPainterJob::cancel()
227227
qDebug("QPAINTER cancelling");
228228
disconnect(&mFutureWatcher, SIGNAL(finished()), this, SLOT(futureFinished()));
229229

230-
mRenderContext.setRenderingStopped(true);
230+
mLabelingRenderContext.setRenderingStopped(true);
231231
for ( LayerRenderJobs::iterator it = mLayerJobs.begin(); it != mLayerJobs.end(); ++it )
232232
{
233233
it->context.setRenderingStopped( true );
@@ -322,32 +322,45 @@ void QgsMapRendererCustomPainterJob::doRender()
322322

323323
QgsDebugMsg( "Done rendering map layers" );
324324

325+
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) && !mLabelingRenderContext.renderingStopped() )
326+
drawLabeling( mSettings, mLabelingRenderContext, mLabelingEngine, mPainter );
327+
328+
QgsDebugMsg( "Rendering completed in (seconds): " + QString( "%1" ).arg( renderTime.elapsed() / 1000.0 ) );
329+
}
330+
331+
332+
void QgsMapRendererJob::drawLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext, QgsPalLabeling* labelingEngine, QPainter* painter )
333+
{
334+
qDebug("Draw labeling start");
335+
336+
QTime t;
337+
t.start();
338+
325339
// Reset the composition mode before rendering the labels
326-
mPainter->setCompositionMode( QPainter::CompositionMode_SourceOver );
340+
painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
327341

328-
mRenderContext = QgsRenderContext::fromMapSettings( mSettings );
329-
mRenderContext.setPainter( mPainter );
330-
mRenderContext.setLabelingEngine( mLabelingEngine );
342+
// TODO: this is not ideal - we could override rendering stopped flag that has been set in meanwhile
343+
renderContext = QgsRenderContext::fromMapSettings( settings );
344+
renderContext.setPainter( painter );
345+
renderContext.setLabelingEngine( labelingEngine );
331346

332347
// old labeling - to be removed at some point...
333-
drawOldLabeling();
348+
drawOldLabeling( settings, renderContext );
334349

335-
drawNewLabeling();
350+
drawNewLabeling( settings, renderContext, labelingEngine );
336351

337-
QgsDebugMsg( "Rendering completed in (seconds): " + QString( "%1" ).arg( renderTime.elapsed() / 1000.0 ) );
352+
qDebug("Draw labeling took (seconds): %f", t.elapsed() / 1000.);
338353
}
339354

340355

341-
void QgsMapRendererCustomPainterJob::drawOldLabeling()
356+
void QgsMapRendererJob::drawOldLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext )
342357
{
343-
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) )
344-
{
345358
// render all labels for vector layers in the stack, starting at the base
346-
QListIterator<QString> li( mSettings.layers() );
359+
QListIterator<QString> li( settings.layers() );
347360
li.toBack();
348361
while ( li.hasPrevious() )
349362
{
350-
if ( mRenderContext.renderingStopped() )
363+
if ( renderContext.renderingStopped() )
351364
{
352365
break;
353366
}
@@ -361,43 +374,42 @@ void QgsMapRendererCustomPainterJob::drawOldLabeling()
361374

362375
// only make labels if the layer is visible
363376
// after scale dep viewing settings are checked
364-
if ( ml->hasScaleBasedVisibility() && ( mSettings.scale() < ml->minimumScale() || mSettings.scale() > ml->maximumScale() ) )
377+
if ( ml->hasScaleBasedVisibility() && ( settings.scale() < ml->minimumScale() || settings.scale() > ml->maximumScale() ) )
365378
continue;
366379

367380
bool split = false;
368381
const QgsCoordinateTransform* ct = 0;
369-
QgsRectangle r1 = mSettings.visibleExtent(), r2;
382+
QgsRectangle r1 = settings.visibleExtent(), r2;
370383

371-
if ( mSettings.hasCrsTransformEnabled() )
384+
if ( settings.hasCrsTransformEnabled() )
372385
{
373-
ct = QgsCoordinateTransformCache::instance()->transform( ml->crs().authid(), mSettings.destinationCrs().authid() );
386+
ct = QgsCoordinateTransformCache::instance()->transform( ml->crs().authid(), settings.destinationCrs().authid() );
374387
split = reprojectToLayerExtent( ct, ml->crs().geographicFlag(), r1, r2 );
375388
}
376389

377-
mRenderContext.setCoordinateTransform( ct );
378-
mRenderContext.setExtent( r1 );
390+
renderContext.setCoordinateTransform( ct );
391+
renderContext.setExtent( r1 );
379392

380-
ml->drawLabels( mRenderContext );
393+
ml->drawLabels( renderContext );
381394
if ( split )
382395
{
383-
mRenderContext.setExtent( r2 );
384-
ml->drawLabels( mRenderContext );
396+
renderContext.setExtent( r2 );
397+
ml->drawLabels( renderContext );
385398
}
386399
}
387-
}
388400
}
389401

390402

391-
void QgsMapRendererCustomPainterJob::drawNewLabeling()
403+
void QgsMapRendererJob::drawNewLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext, QgsPalLabeling* labelingEngine )
392404
{
393-
if ( mLabelingEngine && !mRenderContext.renderingStopped() )
405+
if ( labelingEngine && !renderContext.renderingStopped() )
394406
{
395407
// set correct extent
396-
mRenderContext.setExtent( mSettings.visibleExtent() );
397-
mRenderContext.setCoordinateTransform( NULL );
408+
renderContext.setExtent( settings.visibleExtent() );
409+
renderContext.setCoordinateTransform( NULL );
398410

399-
mLabelingEngine->drawLabeling( mRenderContext );
400-
mLabelingEngine->exit();
411+
labelingEngine->drawLabeling( renderContext );
412+
labelingEngine->exit();
401413
}
402414
}
403415

@@ -611,6 +623,8 @@ void QgsMapRendererJob::cleanupJobs( LayerRenderJobs& jobs )
611623

612624
QgsMapRendererParallelJob::QgsMapRendererParallelJob(const QgsMapSettings& settings)
613625
: QgsMapRendererQImageJob( settings )
626+
, mStatus( Idle )
627+
, mLabelingEngine( 0 )
614628
{
615629
}
616630

@@ -620,16 +634,30 @@ QgsMapRendererParallelJob::~QgsMapRendererParallelJob()
620634
{
621635
cancel();
622636
}
637+
638+
delete mLabelingEngine;
639+
mLabelingEngine = 0;
623640
}
624641

625642
void QgsMapRendererParallelJob::start()
626643
{
627644
if ( isActive() )
628645
return;
629646

630-
// TODO: create labeling engine
647+
mStatus = RenderingLayers;
631648

632-
mLayerJobs = prepareJobs( 0, 0 );
649+
delete mLabelingEngine;
650+
mLabelingEngine = 0;
651+
652+
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) )
653+
{
654+
mLabelingEngine = new QgsPalLabeling;
655+
mLabelingEngine->loadEngineSettings();
656+
mLabelingEngine->init( mSettings );
657+
}
658+
659+
660+
mLayerJobs = prepareJobs( 0, mLabelingEngine );
633661

634662
// start async job
635663

@@ -644,62 +672,122 @@ void QgsMapRendererParallelJob::cancel()
644672
if ( !isActive() )
645673
return;
646674

647-
disconnect(&mFutureWatcher, SIGNAL(finished()), this, SLOT(renderLayersFinished()));
675+
qDebug("PARALLEL cancel at status %d", mStatus);
648676

677+
mLabelingRenderContext.setRenderingStopped( true );
649678
for ( LayerRenderJobs::iterator it = mLayerJobs.begin(); it != mLayerJobs.end(); ++it )
650679
{
651680
it->context.setRenderingStopped( true );
652681
}
653682

654-
mFutureWatcher.waitForFinished();
683+
if ( mStatus == RenderingLayers )
684+
{
685+
disconnect(&mFutureWatcher, SIGNAL(finished()), this, SLOT(renderLayersFinished()));
655686

656-
renderLayersFinished();
687+
mFutureWatcher.waitForFinished();
688+
689+
renderLayersFinished();
690+
}
691+
692+
if ( mStatus == RenderingLabels )
693+
{
694+
disconnect(&mLabelingFutureWatcher, SIGNAL(finished()), this, SLOT(renderingFinished()));
695+
696+
mLabelingFutureWatcher.waitForFinished();
697+
698+
renderingFinished();
699+
}
700+
701+
Q_ASSERT( mStatus == Idle );
657702
}
658703

659704
void QgsMapRendererParallelJob::waitForFinished()
660705
{
661706
if ( !isActive() )
662707
return;
663708

664-
disconnect(&mFutureWatcher, SIGNAL(finished()), this, SLOT(renderLayersFinished()));
709+
if ( mStatus == RenderingLayers )
710+
{
711+
disconnect(&mFutureWatcher, SIGNAL(finished()), this, SLOT(renderLayersFinished()));
712+
713+
QTime t;
714+
t.start();
665715

666-
QTime t;
667-
t.start();
716+
mFutureWatcher.waitForFinished();
668717

669-
mFutureWatcher.waitForFinished();
718+
qDebug("waitForFinished (1): %f ms", t.elapsed() / 1000.0);
670719

671-
qDebug("waitForFinished: %f ms", t.elapsed() / 1000.0);
720+
renderLayersFinished();
721+
}
722+
723+
if ( mStatus == RenderingLabels )
724+
{
725+
disconnect(&mLabelingFutureWatcher, SIGNAL(finished()), this, SLOT(renderingFinished()));
672726

673-
renderLayersFinished();
727+
QTime t;
728+
t.start();
729+
730+
mLabelingFutureWatcher.waitForFinished();
731+
732+
qDebug("waitForFinished (2): %f ms", t.elapsed() / 1000.0);
733+
734+
renderingFinished();
735+
}
736+
737+
Q_ASSERT( mStatus == Idle );
674738
}
675739

676740
bool QgsMapRendererParallelJob::isActive() const
677741
{
678-
return mFutureWatcher.isRunning();
742+
return mStatus != Idle;
679743
}
680744

681745
QgsLabelingResults* QgsMapRendererParallelJob::takeLabelingResults()
682746
{
683-
return 0;
747+
return mLabelingEngine ? mLabelingEngine->takeResults() : 0;
684748
}
685749

686750
QImage QgsMapRendererParallelJob::renderedImage()
687751
{
688-
if ( isActive() )
752+
if ( mStatus == RenderingLayers )
689753
return composeImage();
690754
else
691-
return mFinalImage;
755+
return mFinalImage; // when rendering labels or idle
692756
}
693757

694758
void QgsMapRendererParallelJob::renderLayersFinished()
695759
{
696-
// TODO: now start rendering of labeling!
760+
Q_ASSERT( mStatus == RenderingLayers );
697761

698762
// compose final image
699763
mFinalImage = composeImage();
700764

701765
cleanupJobs( mLayerJobs );
702766

767+
qDebug("PARALLEL layers finished");
768+
769+
if ( mSettings.testFlag( QgsMapSettings::DrawLabeling ) && !mLabelingRenderContext.renderingStopped() )
770+
{
771+
mStatus = RenderingLabels;
772+
773+
connect(&mLabelingFutureWatcher, SIGNAL(finished()), this, SLOT(renderingFinished()));
774+
775+
// now start rendering of labeling!
776+
mLabelingFuture = QtConcurrent::run( renderLabelsStatic, this );
777+
mLabelingFutureWatcher.setFuture(mLabelingFuture);
778+
}
779+
else
780+
{
781+
renderingFinished();
782+
}
783+
}
784+
785+
void QgsMapRendererParallelJob::renderingFinished()
786+
{
787+
qDebug("PARALLEL finished");
788+
789+
mStatus = Idle;
790+
703791
emit finished();
704792
}
705793

@@ -716,6 +804,17 @@ void QgsMapRendererParallelJob::renderLayerStatic(LayerRenderJob& job)
716804
QgsDebugMsg( QString("job %1 end [%2 ms]").arg( (ulong) &job, 0, 16 ).arg( tt ) );
717805
}
718806

807+
808+
void QgsMapRendererParallelJob::renderLabelsStatic(QgsMapRendererParallelJob* self)
809+
{
810+
QPainter painter( &self->mFinalImage );
811+
812+
drawLabeling( self->mSettings, self->mLabelingRenderContext, self->mLabelingEngine, &painter );
813+
814+
painter.end();
815+
}
816+
817+
719818
QImage QgsMapRendererParallelJob::composeImage()
720819
{
721820
QImage image( mSettings.outputSize(), QImage::Format_ARGB32_Premultiplied );

src/core/qgsmaprendererjob.h

+15-3
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ class QgsMapRendererJob : public QObject
8989

9090
bool needTemporaryImage( QgsMapLayer* ml );
9191

92+
static void drawLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext, QgsPalLabeling* labelingEngine, QPainter* painter );
93+
static void drawOldLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext );
94+
static void drawNewLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext, QgsPalLabeling* labelingEngine );
9295

9396
QgsMapSettings mSettings;
9497
Errors mErrors;
@@ -163,22 +166,33 @@ class QgsMapRendererParallelJob : public QgsMapRendererQImageJob
163166
virtual QImage renderedImage();
164167

165168
protected slots:
169+
//! layers are rendered, labeling is still pending
166170
void renderLayersFinished();
171+
//! all rendering is finished, including labeling
172+
void renderingFinished();
167173

168174
protected:
169175

170176
static void renderLayerStatic(LayerRenderJob& job);
177+
static void renderLabelsStatic( QgsMapRendererParallelJob* self );
171178

172179
QImage composeImage();
173180

174181
protected:
175182

176183
QImage mFinalImage;
177184

185+
enum { Idle, RenderingLayers, RenderingLabels } mStatus;
186+
178187
QFuture<void> mFuture;
179188
QFutureWatcher<void> mFutureWatcher;
180189

181190
LayerRenderJobs mLayerJobs;
191+
192+
QgsPalLabeling* mLabelingEngine;
193+
QgsRenderContext mLabelingRenderContext;
194+
QFuture<void> mLabelingFuture;
195+
QFutureWatcher<void> mLabelingFutureWatcher;
182196
};
183197

184198

@@ -207,14 +221,12 @@ protected slots:
207221

208222
// these methods are called within worker thread
209223
void doRender();
210-
void drawOldLabeling();
211-
void drawNewLabeling();
212224

213225
private:
214226
QPainter* mPainter;
215227
QFuture<void> mFuture;
216228
QFutureWatcher<void> mFutureWatcher;
217-
QgsRenderContext mRenderContext; // used just for labeling!
229+
QgsRenderContext mLabelingRenderContext;
218230
QgsPalLabeling* mLabelingEngine;
219231

220232
bool mActive;

0 commit comments

Comments
 (0)