Skip to content
Permalink
Browse files

Stop using QgsMapLayer's setCacheImage()

That caching mechanism is too coarse - it is expected that there is only one map renderer.
Instead, caching would need to be done on higher level, e.g. in QgsMapCanvas
  • Loading branch information
wonder-sk committed Nov 18, 2013
1 parent 68e2951 commit 036b25ebc94af9bc560f9f3f36dcf440dba8391a
@@ -2802,7 +2802,6 @@ void QgsLegend::legendLayerZoomNative()
QgsDebugMsg( "Raster units per pixel : " + QString::number( layer->rasterUnitsPerPixelX() ) );
QgsDebugMsg( "MapUnitsPerPixel before : " + QString::number( mMapCanvas->mapUnitsPerPixel() ) );

layer->setCacheImage( NULL );
if ( mMapCanvas->hasCrsTransformEnabled() )
{
// get legth of central canvas pixel width in source raster crs
@@ -2842,7 +2841,6 @@ void QgsLegend::legendLayerStretchUsingCurrentExtent()
myRectangle = mMapCanvas->mapSettings().outputExtentToLayerExtent( layer, mMapCanvas->extent() );
layer->setContrastEnhancement( contrastEnhancementAlgorithm, QgsRaster::ContrastEnhancementMinMax, myRectangle );

layer->setCacheImage( NULL );
refreshLayerSymbology( layer->id() );
mMapCanvas->refresh();
}
@@ -5815,8 +5815,6 @@ void QgisApp::copyFeatures( QgsFeatureStore & featureStore )

void QgisApp::refreshMapCanvas()
{
//clear all caches first
QgsMapLayerRegistry::instance()->clearAllLayerCaches();
//reload cached provider data
QgsMapLayerRegistry::instance()->reloadAllLayers();
//then refresh
@@ -6856,7 +6854,6 @@ void QgisApp::histogramStretch( bool visibleAreaOnly, QgsRaster::ContrastEnhance

myRasterLayer->setContrastEnhancement( QgsContrastEnhancement::StretchToMinimumMaximum, theLimits, myRectangle );

myRasterLayer->setCacheImage( NULL );
mMapCanvas->refresh();
}

@@ -6913,7 +6910,6 @@ void QgisApp::adjustBrightnessContrast( int delta, bool updateBrightness )
brightnessFilter->setContrast( brightnessFilter->contrast() + delta );
}

myRasterLayer->setCacheImage( NULL );
mMapCanvas->refresh();
}

@@ -930,9 +930,6 @@ void QgsRasterLayerProperties::apply()
// update symbology
emit refreshLegend( mRasterLayer->id(), false );

//no need to delete the old one, maplayer will do it if needed
mRasterLayer->setCacheImage( 0 );

//make sure the layer is redrawn
mRasterLayer->triggerRepaint();

@@ -532,9 +532,6 @@ void QgsVectorLayerProperties::apply()
// update symbology
emit refreshLegend( layer->id(), QgsLegendItem::DontChange );

//no need to delete the old one, maplayer will do it if needed
layer->setCacheImage( 0 );

layer->triggerRepaint();
// notify the project we've made a change
QgsProject::instance()->dirty( true );
@@ -1341,7 +1341,6 @@ void QgsMapLayer::setValid( bool valid )

void QgsMapLayer::clearCacheImage()
{
setCacheImage( 0 );
}

QString QgsMapLayer::metadata()
@@ -360,12 +360,12 @@ class CORE_EXPORT QgsMapLayer : public QObject
/** Return pointer to layer's undo stack */
QUndoStack* undoStack();

/** \note Deprecated from 2.1 - returns NULL */
QImage *cacheImage() { return 0; }
/** \note Deprecated from 2.1 - does nothing */
void setCacheImage( QImage * ) {}
/** @note Deprecated from 2.1 - does nothing */
virtual void onCacheImageDelete() {}
/** @deprecated since 2.1 - returns NULL */
Q_DECL_DEPRECATED QImage *cacheImage() { return 0; }
/** @deprecated since 2.1 - does nothing */
Q_DECL_DEPRECATED void setCacheImage( QImage * ) {}
/** @deprecated since 2.1 - does nothing */
Q_DECL_DEPRECATED virtual void onCacheImageDelete() {}

public slots:

@@ -386,7 +386,8 @@ class CORE_EXPORT QgsMapLayer : public QObject

/** Clear cached image
* added in 1.5 */
void clearCacheImage();
//! @deprecated in 2.1 - does nothing
Q_DECL_DEPRECATED void clearCacheImage();

/** \brief Obtain Metadata for this layer */
virtual QString metadata();
@@ -151,16 +151,9 @@ void QgsMapLayerRegistry::removeAllMapLayers()
mMapLayers.clear();
} // QgsMapLayerRegistry::removeAllMapLayers()

//Added in QGIS 1.4
void QgsMapLayerRegistry::clearAllLayerCaches()
{
QMap<QString, QgsMapLayer *>::iterator it;
for ( it = mMapLayers.begin(); it != mMapLayers.end() ; ++it )
{
//the map layer will take care of deleting the QImage
it.value()->setCacheImage( 0 );
}
} // QgsMapLayerRegistry::clearAllLayerCaches()
}

void QgsMapLayerRegistry::reloadAllLayers()
{
@@ -150,7 +150,8 @@ class CORE_EXPORT QgsMapLayerRegistry : public QObject
*
* @note Added in QGIS 1.4
*/
void clearAllLayerCaches();
//! @deprecated since 2.1 - does nothing
Q_DECL_DEPRECATED void clearAllLayerCaches();

/**
* Reload all provider data caches (currently used for WFS and WMS providers)
@@ -329,18 +329,6 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
if ( mLabelingEngine )
mLabelingEngine->init( this );

// know we know if this render is just a repeat of the last time, we
// can clear caches if it has changed
if ( !mySameAsLastFlag )
{
//clear the cache pixmap if we changed resolution / extent
QSettings mySettings;
if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
{
QgsMapLayerRegistry::instance()->clearAllLayerCaches();
}
}

// render all layers in the stack, starting at the base
QListIterator<QString> li( mLayerSet );
li.toBack();
@@ -439,58 +427,7 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
scaleRaster = true;
}

// Force render of layers that are being edited
// or if there's a labeling engine that needs the layer to register features
if ( ml->type() == QgsMapLayer::VectorLayer )
{
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
if ( vl->isEditable() ||
( mRenderContext.labelingEngine() && mRenderContext.labelingEngine()->willUseLayer( vl ) ) )
{
ml->setCacheImage( 0 );
}
}

QSettings mySettings;
bool useRenderCaching = false;
if ( ! split )//render caching does not yet cater for split extents
{
if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
{
useRenderCaching = true;
if ( !mySameAsLastFlag || ml->cacheImage() == 0 )
{
QgsDebugMsg( "Caching enabled but layer redraw forced by extent change or empty cache" );
QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(),
mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
if ( mypImage->isNull() )
{
QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) );
emit drawError( ml );
painter->end(); // drawError is not caught by anyone, so we end painting to notify caller
return;
}
mypImage->fill( 0 );
ml->setCacheImage( mypImage ); //no need to delete the old one, maplayer does it for you
QPainter * mypPainter = new QPainter( ml->cacheImage() );
// Changed to enable anti aliasing by default in QGIS 1.7
if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
{
mypPainter->setRenderHint( QPainter::Antialiasing );
}
mRenderContext.setPainter( mypPainter );
}
else if ( mySameAsLastFlag )
{
//draw from cached image
QgsDebugMsg( "Caching enabled --- drawing layer from cached image" );
mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
//short circuit as there is nothing else to do...
continue;
}
}
}

// 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
@@ -500,8 +437,7 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
{
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
if (( !useRenderCaching )
&& (( vl->blendMode() != QPainter::CompositionMode_SourceOver )
if ( (( vl->blendMode() != QPainter::CompositionMode_SourceOver )
|| ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver )
|| ( vl->layerTransparency() != 0 ) ) )
{
@@ -589,17 +525,7 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
}
}

if ( useRenderCaching )
{
// composite the cached image into our view and then clean up from caching
// by reinstating the painter as it was swapped out for caching renders
delete mRenderContext.painter();
mRenderContext.setPainter( mypContextPainter );
//draw from cached image that we created further up
if ( ml->cacheImage() )
mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
}
else if ( flattenedLayer )
if ( flattenedLayer )
{
// If we flattened this layer for alternate blend modes, composite it now
delete mRenderContext.painter();
@@ -133,7 +133,6 @@ QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
, mDiagramLayerSettings( 0 )
, mValidExtent( false )
, mSymbolFeatureCounted( false )
, mCurrentRendererContext( 0 )

{
mActions = new QgsAttributeAction( this );
@@ -388,8 +387,6 @@ void QgsVectorLayer::drawRendererV2( QgsFeatureIterator &fit, QgsRenderContext&
if ( !hasGeometryType() )
return;

mCurrentRendererContext = &rendererContext;

QSettings settings;
bool vertexMarkerOnlyForSelection = settings.value( "/qgis/digitizing/marker_only_for_selected", false ).toBool();

@@ -441,8 +438,6 @@ void QgsVectorLayer::drawRendererV2( QgsFeatureIterator &fit, QgsRenderContext&
}

stopRendererV2( rendererContext, NULL );

mCurrentRendererContext = NULL;
}

void QgsVectorLayer::drawRendererV2Levels( QgsFeatureIterator &fit, QgsRenderContext& rendererContext, bool labeling )
@@ -647,31 +642,27 @@ void QgsVectorLayer::select( const QgsFeatureId& fid )
{
mSelectedFeatureIds.insert( fid );

setCacheImage( 0 );
emit selectionChanged( QgsFeatureIds() << fid, QgsFeatureIds(), false );
}

void QgsVectorLayer::select( const QgsFeatureIds& featureIds )
{
mSelectedFeatureIds.unite( featureIds );

setCacheImage( 0 );
emit selectionChanged( featureIds, QgsFeatureIds(), false );
}

void QgsVectorLayer::deselect( const QgsFeatureId fid )
{
mSelectedFeatureIds.remove( fid );

setCacheImage( 0 );
emit selectionChanged( QgsFeatureIds(), QgsFeatureIds() << fid, false );
}

void QgsVectorLayer::deselect( const QgsFeatureIds& featureIds )
{
mSelectedFeatureIds.subtract( featureIds );

setCacheImage( 0 );
emit selectionChanged( QgsFeatureIds(), featureIds, false );
}

@@ -715,8 +706,6 @@ void QgsVectorLayer::modifySelection( QgsFeatureIds selectIds, QgsFeatureIds des
mSelectedFeatureIds -= deselectIds;
mSelectedFeatureIds += selectIds;

setCacheImage( 0 );

emit selectionChanged( selectIds, deselectIds - intersectingIds, false );
}

@@ -1127,9 +1116,6 @@ bool QgsVectorLayer::setSubsetString( QString subset )
mDataSource = mDataProvider->dataSourceUri();
updateExtents();

if ( res )
setCacheImage( 0 );

return res;
}

@@ -1252,8 +1238,6 @@ bool QgsVectorLayer::deleteSelectedFeatures()
deleteFeature( fid ); // removes from selection
}

// invalidate cache
setCacheImage( 0 );
triggerRepaint();
updateExtents();

@@ -2572,9 +2556,6 @@ bool QgsVectorLayer::commitChanges()
updateFields();
mDataProvider->updateExtents();

//clear the cache image so markers don't appear anymore on next draw
setCacheImage( 0 );

return success;
}

@@ -2616,9 +2597,6 @@ bool QgsVectorLayer::rollBack( bool deleteBuffer )
mCache->deleteCachedGeometries();
}

// invalidate the cache so the layer updates properly to show its original
// after the rollback
setCacheImage( 0 );
return true;
}

@@ -2642,9 +2620,6 @@ void QgsVectorLayer::setSelectedFeatures( const QgsFeatureIds& ids )
}
}

// invalidate cache
setCacheImage( 0 );

emit selectionChanged( ids, deselectedFeatures, true );
}

@@ -3763,12 +3738,6 @@ QString QgsVectorLayer::metadata()
return myMetadata;
}

void QgsVectorLayer::onCacheImageDelete()
{
if ( mCurrentRendererContext )
mCurrentRendererContext->setRenderingStopped( true );
}

void QgsVectorLayer::invalidateSymbolCountedFlag()
{
mSymbolFeatureCounted = false;
@@ -1418,12 +1418,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
@note added in 1.7 */
void checkJoinLayerRemove( QString theLayerId );

/**
* @brief Is called when the cache image is being deleted. Overwrite and use to clean up.
* @note added in 2.0
*/
virtual void onCacheImageDelete();

protected slots:
void invalidateSymbolCountedFlag();

@@ -1575,8 +1569,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/** Pointer to data provider derived from the abastract base class QgsDataProvider */
QgsVectorDataProvider *mDataProvider;

QgsFeatureIterator mProviderIterator;

/** index of the primary label field */
QString mDisplayField;

@@ -1696,8 +1688,6 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
// Feature counts for each renderer symbol
QMap<QgsSymbolV2*, long> mSymbolFeatureCountMap;

QgsRenderContext* mCurrentRendererContext;

friend class QgsVectorLayerFeatureIterator;
};

0 comments on commit 036b25e

Please sign in to comment.
You can’t perform that action at this time.