Skip to content

Commit

Permalink
Optimize simple marker rendering perfomance
Browse files Browse the repository at this point in the history
expression( "..." ) call create QString object at every invocation. For
layers with simple markers this overhead take upto 10% of rendering time.

Move expression finding to startRender() method.

Signed-off-by: Yauhen Kharuzhy <jekhor@gmail.com>
  • Loading branch information
jekhor authored and mhugent committed Dec 9, 2013
1 parent 93e0f3d commit 7d8d1d6
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 16 deletions.
18 changes: 11 additions & 7 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
Expand Up @@ -46,6 +46,8 @@ QgsSimpleMarkerSymbolLayerV2::QgsSimpleMarkerSymbolLayerV2( QString name, QColor
mScaleMethod = scaleMethod;
mSizeUnit = QgsSymbolV2::MM;
mOffsetUnit = QgsSymbolV2::MM;
mAngleExpression = NULL;
mNameExpression = NULL;
}

QgsSymbolLayerV2* QgsSimpleMarkerSymbolLayerV2::create( const QgsStringMap& props )
Expand Down Expand Up @@ -231,6 +233,10 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
}

prepareExpressions( context.layer(), context.renderContext().rendererScale() );
mAngleExpression = expression( "angle" );
mNameExpression = expression( "name" );

QgsMarkerSymbolLayerV2::startRender( context );
}


Expand Down Expand Up @@ -456,19 +462,17 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV

//angle
double angle = mAngle;
QgsExpression* angleExpression = expression( "angle" );
if ( angleExpression )
if ( mAngleExpression )
{
angle = angleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
angle = mAngleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
}
if ( angle )
off = _rotatedOffset( off, angle );

//data defined shape?
QgsExpression* nameExpression = expression( "name" );
if ( nameExpression )
if ( mNameExpression )
{
QString name = nameExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
QString name = mNameExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
if ( !prepareShape( name ) ) // drawing as a polygon
{
preparePath( name ); // drawing as a painter path
Expand Down Expand Up @@ -517,7 +521,7 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
transform.scale( half, half );
}

bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation || angleExpression;
bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation || mAngleExpression;
if ( angle != 0 && hasDataDefinedRotation )
transform.rotate( angle );

Expand Down
4 changes: 4 additions & 0 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.h
Expand Up @@ -105,6 +105,10 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2

//Maximum width/height of cache image
static const int mMaximumCacheWidth = 3000;

private:
QgsExpression *mAngleExpression;
QgsExpression *mNameExpression;
};

//////////
Expand Down
25 changes: 16 additions & 9 deletions src/core/symbology-ng/qgssymbollayerv2.cpp
Expand Up @@ -173,6 +173,9 @@ QgsMarkerSymbolLayerV2::QgsMarkerSymbolLayerV2( bool locked )
: QgsSymbolLayerV2( QgsSymbolV2::Marker, locked ), mSizeUnit( QgsSymbolV2::MM ), mOffsetUnit( QgsSymbolV2::MM ),
mHorizontalAnchorPoint( HCenter ), mVerticalAnchorPoint( VCenter )
{
mOffsetExpression = NULL;
mHorizontalAnchorExpression = NULL;
mVerticalAnchorExpression = NULL;
}

QgsLineSymbolLayerV2::QgsLineSymbolLayerV2( bool locked )
Expand All @@ -185,6 +188,13 @@ QgsFillSymbolLayerV2::QgsFillSymbolLayerV2( bool locked )
{
}

void QgsMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
{
mOffsetExpression = expression( "offset" );
mHorizontalAnchorExpression = expression( "horizontal_anchor_point" );
mVerticalAnchorExpression = expression( "vertical_anchor_point" );
}

void QgsMarkerSymbolLayerV2::drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size )
{
startRender( context );
Expand All @@ -210,10 +220,9 @@ void QgsMarkerSymbolLayerV2::markerOffset( const QgsSymbolV2RenderContext& conte
offsetX = mOffset.x();
offsetY = mOffset.y();

QgsExpression* offsetExpression = expression( "offset" );
if ( offsetExpression )
if ( mOffsetExpression )
{
QPointF offset = QgsSymbolLayerV2Utils::decodePoint( offsetExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
QPointF offset = QgsSymbolLayerV2Utils::decodePoint( mOffsetExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
offsetX = offset.x();
offsetY = offset.y();
}
Expand All @@ -223,15 +232,13 @@ void QgsMarkerSymbolLayerV2::markerOffset( const QgsSymbolV2RenderContext& conte

HorizontalAnchorPoint horizontalAnchorPoint = mHorizontalAnchorPoint;
VerticalAnchorPoint verticalAnchorPoint = mVerticalAnchorPoint;
QgsExpression* horizontalAnchorExpression = expression( "horizontal_anchor_point" );
if ( horizontalAnchorExpression )
if ( mHorizontalAnchorExpression )
{
horizontalAnchorPoint = decodeHorizontalAnchorPoint( horizontalAnchorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
horizontalAnchorPoint = decodeHorizontalAnchorPoint( mHorizontalAnchorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
}
QgsExpression* verticalAnchorExpression = expression( "vertical_anchor_point" );
if ( verticalAnchorExpression )
if ( mVerticalAnchorExpression )
{
verticalAnchorPoint = decodeVerticalAnchorPoint( verticalAnchorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
verticalAnchorPoint = decodeVerticalAnchorPoint( mVerticalAnchorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
}

//correct horizontal position according to anchor point
Expand Down
6 changes: 6 additions & 0 deletions src/core/symbology-ng/qgssymbollayerv2.h
Expand Up @@ -146,6 +146,8 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
Bottom
};

void startRender( QgsSymbolV2RenderContext& context );

virtual void renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ) = 0;

void drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size );
Expand Down Expand Up @@ -205,6 +207,10 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
private:
static QgsMarkerSymbolLayerV2::HorizontalAnchorPoint decodeHorizontalAnchorPoint( const QString& str );
static QgsMarkerSymbolLayerV2::VerticalAnchorPoint decodeVerticalAnchorPoint( const QString& str );

QgsExpression* mOffsetExpression;
QgsExpression* mHorizontalAnchorExpression;
QgsExpression* mVerticalAnchorExpression;
};

class CORE_EXPORT QgsLineSymbolLayerV2 : public QgsSymbolLayerV2
Expand Down

0 comments on commit 7d8d1d6

Please sign in to comment.