[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.
This commit is contained in:
Even Rouault 2017-11-15 20:10:08 +01:00 committed by Nyall Dawson
parent 32ba5bf23f
commit 997619c9ed
10 changed files with 70 additions and 2 deletions

View File

@ -241,6 +241,8 @@ const double DEFAULT_LINE_WIDTH;
const double DEFAULT_SEGMENT_EPSILON;
typedef unsigned long long qgssize;

View File

@ -916,6 +916,7 @@ Time stamp of data source in the moment when data/metadata were loaded by provid
:rtype: bool
%End
public slots:
void setMinimumScale( double scale );

View File

@ -440,6 +440,18 @@ const double DEFAULT_LINE_WIDTH = 0.26;
//! Default snapping tolerance for segments
const double DEFAULT_SEGMENT_EPSILON = 1e-8;
///@cond PRIVATE
#ifndef SIP_RUN
//! Delay between the scheduling of 2 preview jobs
const int PREVIEW_JOB_DELAY_MS = 250;
//! Maximum rendering time for a layer of a preview job
const int MAXIMUM_LAYER_PREVIEW_TIME_MS = 250;
#endif
///@endcond
typedef QMap<QString, QString> QgsStringMap SIP_SKIP;
/**

View File

@ -42,3 +42,7 @@ void QgsDataProvider::setListening( bool isListening )
Q_UNUSED( isListening );
}
bool QgsDataProvider::renderInPreview( double lastRenderingTimeMS, double maxRenderingTimeMS )
{
return lastRenderingTimeMS <= maxRenderingTimeMS;
}

View File

@ -461,6 +461,21 @@ class CORE_EXPORT QgsDataProvider : public QObject
*/
virtual void setListening( bool isListening );
/**
* Returns whether the layer must be rendered in preview jobs.
*
* The base implementation returns lastRenderingTimeMS <= maxRenderingTimeMS
*
* \param lastRenderingTimeMS last rendering time in milliseconds.
* \param maxRenderingTimeMS maximum allowed rendering time in milliseconds.
* \returns true if the layer must be rendered.
*
* \since QGIS 3.0
*
* \note not available in Python bindings
*/
virtual bool renderInPreview( double lastRenderingTimeMS, double maxRenderingTimeMS ); // SIP_SKIP
signals:
/**

View File

@ -882,6 +882,25 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
bool isRefreshOnNotifyEnabled() const { return mIsRefreshOnNofifyEnabled; }
///@cond PRIVATE
#ifndef SIP_RUN
/**
* Set last rendering time.
*
* \note not available in Python bindings
*/
void setLastRenderingTime( double time ) { mLastRenderingTime = time; }
/**
* Get last rendering time.
*
* \note not available in Python bindings
*/
double lastRenderingTime() const { return mLastRenderingTime; }
#endif
///@endcond
public slots:
/**
@ -1221,6 +1240,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
//! Renderer for 3D views
QgsAbstract3DRenderer *m3DRenderer = nullptr;
double mLastRenderingTime = 0.0;
};
Q_DECLARE_METATYPE( QgsMapLayer * )

View File

@ -265,6 +265,10 @@ void QgsMapRendererCustomPainterJob::doRender()
job.renderer->render();
job.renderingTime = layerTime.elapsed();
if ( job.layer )
{
job.layer->setLastRenderingTime( job.renderingTime );
}
}
if ( job.img )

View File

@ -242,6 +242,13 @@ LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter *painter, QgsLabelingEn
continue;
}
if ( ( mSettings.flags() & QgsMapSettings::RenderPreviewJob ) &&
!ml->dataProvider()->renderInPreview( ml->lastRenderingTime(), MAXIMUM_LAYER_PREVIEW_TIME_MS ) )
{
QgsDebugMsgLevel( "Layer not rendered because it does not match the renderInPreview criterion", 3 );
continue;
}
QgsRectangle r1 = mSettings.visibleExtent(), r2;
QgsCoordinateTransform ct;

View File

@ -270,6 +270,10 @@ void QgsMapRendererParallelJob::renderLayerStatic( LayerRenderJob &job )
QgsDebugMsg( "Caught unhandled unknown exception" );
}
job.renderingTime = t.elapsed();
if ( job.layer )
{
job.layer->setLastRenderingTime( job.renderingTime );
}
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 );
}

View File

@ -66,7 +66,6 @@ email : sherman at mrcc.com
#include "qgsmapthemecollection.h"
#include <cmath>
/**
* \ingroup gui
* Deprecated to be deleted, stuff from here should be moved elsewhere.
@ -2299,7 +2298,7 @@ void QgsMapCanvas::stopPreviewJobs()
void QgsMapCanvas::schedulePreviewJob( int number )
{
mPreviewTimer.setSingleShot( true );
mPreviewTimer.setInterval( 250 );
mPreviewTimer.setInterval( PREVIEW_JOB_DELAY_MS );
disconnect( mPreviewTimerConnection );
mPreviewTimerConnection = connect( &mPreviewTimer, &QTimer::timeout, this, [ = ]()
{