Skip to content

Commit

Permalink
Add API to pass approximate layer rendering time estimatation to
Browse files Browse the repository at this point in the history
map layer renderers

These renderers can then use the layer rendering time for the previous
map render job to refine their logic regarding when its appropriate
to start compositing the layer render
  • Loading branch information
nyalldawson committed Jan 27, 2021
1 parent ff36aa0 commit bb746c6
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 1 deletion.
1 change: 1 addition & 0 deletions python/core/auto_generated/qgsmaplayerrenderer.sip.in
Expand Up @@ -104,6 +104,7 @@ least partially) some data
.. versionadded:: 3.18
%End


protected:


Expand Down
2 changes: 2 additions & 0 deletions python/core/auto_generated/qgsmaprendererjob.sip.in
Expand Up @@ -145,6 +145,7 @@ Returns the total time it took to finish the job (in milliseconds).
%End



const QgsMapSettings &mapSettings() const;
%Docstring
Returns map settings with which this job was started.
Expand Down Expand Up @@ -191,6 +192,7 @@ emitted when asynchronous rendering is finished (or canceled).




};


Expand Down
12 changes: 12 additions & 0 deletions src/core/qgsmaplayerrenderer.h
Expand Up @@ -118,6 +118,18 @@ class CORE_EXPORT QgsMapLayerRenderer
*/
bool isReadyToCompose() const { return mReadyToCompose; }

/**
* Sets approximate render \a time (in ms) for the layer to render.
*
* This can be used to specifies a hint at the expected render times for the layer, so that
* the individual layer renderer subclasses can apply heuristics and determine appropriate update
* intervals during the render operation.
*
* \note Not available in Python bindings.
* \since QGIS 3.18
*/
virtual void setLayerRenderingTimeHint( int time ) SIP_SKIP { Q_UNUSED( time ) }

protected:
QStringList mErrors;
QString mLayerID;
Expand Down
10 changes: 9 additions & 1 deletion src/core/qgsmaprendererjob.cpp
Expand Up @@ -95,12 +95,17 @@ QHash<QgsMapLayer *, int> QgsMapRendererJob::perLayerRenderingTime() const
QHash<QgsMapLayer *, int> result;
for ( auto it = mPerLayerRenderingTime.constBegin(); it != mPerLayerRenderingTime.constEnd(); ++it )
{
if ( auto &&lKey = it.key() )
if ( auto && lKey = it.key() )
result.insert( lKey, it.value() );
}
return result;
}

void QgsMapRendererJob::setLayerRenderingTimeHints( const QHash<QString, int> &hints )
{
mLayerRenderingTimeHints = hints;
}

const QgsMapSettings &QgsMapRendererJob::mapSettings() const
{
return mSettings;
Expand Down Expand Up @@ -399,6 +404,7 @@ LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter *painter, QgsLabelingEn
job.img = nullptr;
job.layer = ml;
job.layerId = ml->id();
job.estimatedRenderingTime = mLayerRenderingTimeHints.value( ml->id(), 0 );
job.renderingTime = -1;

job.context = QgsRenderContext::fromMapSettings( mSettings );
Expand Down Expand Up @@ -438,6 +444,8 @@ LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter *painter, QgsLabelingEn
QElapsedTimer layerTime;
layerTime.start();
job.renderer = ml->createMapRenderer( job.context );
if ( job.renderer )
job.renderer->setLayerRenderingTimeHint( job.estimatedRenderingTime );

// If we are drawing with an alternative blending mode then we need to render to a separate image
// before compositing this on the map. This effectively flattens the layer and prevents
Expand Down
33 changes: 33 additions & 0 deletions src/core/qgsmaprendererjob.h
Expand Up @@ -65,6 +65,18 @@ struct LayerRenderJob
bool cached;
QgsWeakMapLayerPointer layer;
int renderingTime; //!< Time it took to render the layer in ms (it is -1 if not rendered or still rendering)

/**
* Estimated time for the layer to render, in ms.
*
* This can be used to specifies hints at the expected render times for the layer, so that
* the corresponding layer renderer can apply heuristics and determine appropriate update
* intervals during the render operation.
*
* \since QGIS 3.18
*/
int estimatedRenderingTime = 0;

QStringList errors; //!< Rendering errors

/**
Expand Down Expand Up @@ -286,6 +298,20 @@ class CORE_EXPORT QgsMapRendererJob : public QObject
*/
QHash< QgsMapLayer *, int > perLayerRenderingTime() const SIP_SKIP;

/**
* Sets approximate render times (in ms) for map layers.
*
* This can be used to specifies hints at the expected render times for layers, so that
* the individual layer renderers can apply heuristics and determine appropriate update
* intervals during the render operation.
*
* The keys for \a hints must be set to the corresponding layer IDs.
*
* \note Not available in Python bindings.
* \since QGIS 3.18
*/
void setLayerRenderingTimeHints( const QHash< QString, int > &hints ) SIP_SKIP;

/**
* Returns map settings with which this job was started.
* \returns A QgsMapSettings instance with render settings
Expand Down Expand Up @@ -326,6 +352,13 @@ class CORE_EXPORT QgsMapRendererJob : public QObject
//! Render time (in ms) per layer, by layer ID
QHash< QgsWeakMapLayerPointer, int > mPerLayerRenderingTime;

/**
* Approximate expected layer rendering time per layer, by layer ID
*
* \since QGIS 3.18
*/
QHash< QString, int > mLayerRenderingTimeHints;

/**
* TRUE if layer rendering time should be recorded.
*/
Expand Down
2 changes: 2 additions & 0 deletions src/gui/qgsmapcanvas.cpp
Expand Up @@ -604,8 +604,10 @@ void QgsMapCanvas::refreshMap()
mJob = new QgsMapRendererParallelJob( renderSettings );
else
mJob = new QgsMapRendererSequentialJob( renderSettings );

connect( mJob, &QgsMapRendererJob::finished, this, &QgsMapCanvas::rendererJobFinished );
mJob->setCache( mCache );
mJob->setLayerRenderingTimeHints( mLastLayerRenderTime );

mJob->start();

Expand Down

0 comments on commit bb746c6

Please sign in to comment.