Skip to content

Commit 997619c

Browse files
rouaultnyalldawson
authored andcommitted
[Rendering] Only render in preview jobs layers that are fast enough
This implements the improvements discussed in the mailing list thread https://lists.osgeo.org/pipermail/qgis-developer/2017-November/050524.html to avoid rendering layers in preview jobs that take too much time to render.
1 parent 32ba5bf commit 997619c

10 files changed

+70
-2
lines changed

python/core/qgis.sip

+2
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ const double DEFAULT_LINE_WIDTH;
241241
const double DEFAULT_SEGMENT_EPSILON;
242242

243243

244+
245+
244246
typedef unsigned long long qgssize;
245247

246248

python/core/qgsmaplayer.sip

+1
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,7 @@ Time stamp of data source in the moment when data/metadata were loaded by provid
916916
:rtype: bool
917917
%End
918918

919+
919920
public slots:
920921

921922
void setMinimumScale( double scale );

src/core/qgis.h

+12
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,18 @@ const double DEFAULT_LINE_WIDTH = 0.26;
440440
//! Default snapping tolerance for segments
441441
const double DEFAULT_SEGMENT_EPSILON = 1e-8;
442442

443+
///@cond PRIVATE
444+
#ifndef SIP_RUN
445+
446+
//! Delay between the scheduling of 2 preview jobs
447+
const int PREVIEW_JOB_DELAY_MS = 250;
448+
449+
//! Maximum rendering time for a layer of a preview job
450+
const int MAXIMUM_LAYER_PREVIEW_TIME_MS = 250;
451+
#endif
452+
453+
///@endcond
454+
443455
typedef QMap<QString, QString> QgsStringMap SIP_SKIP;
444456

445457
/**

src/core/qgsdataprovider.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,7 @@ void QgsDataProvider::setListening( bool isListening )
4242
Q_UNUSED( isListening );
4343
}
4444

45+
bool QgsDataProvider::renderInPreview( double lastRenderingTimeMS, double maxRenderingTimeMS )
46+
{
47+
return lastRenderingTimeMS <= maxRenderingTimeMS;
48+
}

src/core/qgsdataprovider.h

+15
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,21 @@ class CORE_EXPORT QgsDataProvider : public QObject
461461
*/
462462
virtual void setListening( bool isListening );
463463

464+
/**
465+
* Returns whether the layer must be rendered in preview jobs.
466+
*
467+
* The base implementation returns lastRenderingTimeMS <= maxRenderingTimeMS
468+
*
469+
* \param lastRenderingTimeMS last rendering time in milliseconds.
470+
* \param maxRenderingTimeMS maximum allowed rendering time in milliseconds.
471+
* \returns true if the layer must be rendered.
472+
*
473+
* \since QGIS 3.0
474+
*
475+
* \note not available in Python bindings
476+
*/
477+
virtual bool renderInPreview( double lastRenderingTimeMS, double maxRenderingTimeMS ); // SIP_SKIP
478+
464479
signals:
465480

466481
/**

src/core/qgsmaplayer.h

+20
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,25 @@ class CORE_EXPORT QgsMapLayer : public QObject
882882
*/
883883
bool isRefreshOnNotifyEnabled() const { return mIsRefreshOnNofifyEnabled; }
884884

885+
///@cond PRIVATE
886+
#ifndef SIP_RUN
887+
888+
/**
889+
* Set last rendering time.
890+
*
891+
* \note not available in Python bindings
892+
*/
893+
void setLastRenderingTime( double time ) { mLastRenderingTime = time; }
894+
895+
/**
896+
* Get last rendering time.
897+
*
898+
* \note not available in Python bindings
899+
*/
900+
double lastRenderingTime() const { return mLastRenderingTime; }
901+
#endif
902+
///@endcond
903+
885904
public slots:
886905

887906
/**
@@ -1221,6 +1240,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
12211240
//! Renderer for 3D views
12221241
QgsAbstract3DRenderer *m3DRenderer = nullptr;
12231242

1243+
double mLastRenderingTime = 0.0;
12241244
};
12251245

12261246
Q_DECLARE_METATYPE( QgsMapLayer * )

src/core/qgsmaprenderercustompainterjob.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ void QgsMapRendererCustomPainterJob::doRender()
265265
job.renderer->render();
266266

267267
job.renderingTime = layerTime.elapsed();
268+
if ( job.layer )
269+
{
270+
job.layer->setLastRenderingTime( job.renderingTime );
271+
}
268272
}
269273

270274
if ( job.img )

src/core/qgsmaprendererjob.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,13 @@ LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter *painter, QgsLabelingEn
242242
continue;
243243
}
244244

245+
if ( ( mSettings.flags() & QgsMapSettings::RenderPreviewJob ) &&
246+
!ml->dataProvider()->renderInPreview( ml->lastRenderingTime(), MAXIMUM_LAYER_PREVIEW_TIME_MS ) )
247+
{
248+
QgsDebugMsgLevel( "Layer not rendered because it does not match the renderInPreview criterion", 3 );
249+
continue;
250+
}
251+
245252
QgsRectangle r1 = mSettings.visibleExtent(), r2;
246253
QgsCoordinateTransform ct;
247254

src/core/qgsmaprendererparalleljob.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ void QgsMapRendererParallelJob::renderLayerStatic( LayerRenderJob &job )
270270
QgsDebugMsg( "Caught unhandled unknown exception" );
271271
}
272272
job.renderingTime = t.elapsed();
273+
if ( job.layer )
274+
{
275+
job.layer->setLastRenderingTime( job.renderingTime );
276+
}
273277
QgsDebugMsgLevel( QString( "job %1 end [%2 ms] (layer %3)" ).arg( reinterpret_cast< quint64 >( &job ), 0, 16 ).arg( job.renderingTime ).arg( job.layer ? job.layer->id() : QString() ), 2 );
274278
}
275279

src/gui/qgsmapcanvas.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ email : sherman at mrcc.com
6666
#include "qgsmapthemecollection.h"
6767
#include <cmath>
6868

69-
7069
/**
7170
* \ingroup gui
7271
* Deprecated to be deleted, stuff from here should be moved elsewhere.
@@ -2299,7 +2298,7 @@ void QgsMapCanvas::stopPreviewJobs()
22992298
void QgsMapCanvas::schedulePreviewJob( int number )
23002299
{
23012300
mPreviewTimer.setSingleShot( true );
2302-
mPreviewTimer.setInterval( 250 );
2301+
mPreviewTimer.setInterval( PREVIEW_JOB_DELAY_MS );
23032302
disconnect( mPreviewTimerConnection );
23042303
mPreviewTimerConnection = connect( &mPreviewTimer, &QTimer::timeout, this, [ = ]()
23052304
{

0 commit comments

Comments
 (0)