Skip to content

Commit 7d8d1d6

Browse files
jekhormhugent
authored andcommitted
Optimize simple marker rendering perfomance
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>
1 parent 93e0f3d commit 7d8d1d6

File tree

4 files changed

+37
-16
lines changed

4 files changed

+37
-16
lines changed

src/core/symbology-ng/qgsmarkersymbollayerv2.cpp

+11-7
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ QgsSimpleMarkerSymbolLayerV2::QgsSimpleMarkerSymbolLayerV2( QString name, QColor
4646
mScaleMethod = scaleMethod;
4747
mSizeUnit = QgsSymbolV2::MM;
4848
mOffsetUnit = QgsSymbolV2::MM;
49+
mAngleExpression = NULL;
50+
mNameExpression = NULL;
4951
}
5052

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

233235
prepareExpressions( context.layer(), context.renderContext().rendererScale() );
236+
mAngleExpression = expression( "angle" );
237+
mNameExpression = expression( "name" );
238+
239+
QgsMarkerSymbolLayerV2::startRender( context );
234240
}
235241

236242

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

457463
//angle
458464
double angle = mAngle;
459-
QgsExpression* angleExpression = expression( "angle" );
460-
if ( angleExpression )
465+
if ( mAngleExpression )
461466
{
462-
angle = angleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
467+
angle = mAngleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
463468
}
464469
if ( angle )
465470
off = _rotatedOffset( off, angle );
466471

467472
//data defined shape?
468-
QgsExpression* nameExpression = expression( "name" );
469-
if ( nameExpression )
473+
if ( mNameExpression )
470474
{
471-
QString name = nameExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
475+
QString name = mNameExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString();
472476
if ( !prepareShape( name ) ) // drawing as a polygon
473477
{
474478
preparePath( name ); // drawing as a painter path
@@ -517,7 +521,7 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
517521
transform.scale( half, half );
518522
}
519523

520-
bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation || angleExpression;
524+
bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation || mAngleExpression;
521525
if ( angle != 0 && hasDataDefinedRotation )
522526
transform.rotate( angle );
523527

src/core/symbology-ng/qgsmarkersymbollayerv2.h

+4
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
105105

106106
//Maximum width/height of cache image
107107
static const int mMaximumCacheWidth = 3000;
108+
109+
private:
110+
QgsExpression *mAngleExpression;
111+
QgsExpression *mNameExpression;
108112
};
109113

110114
//////////

src/core/symbology-ng/qgssymbollayerv2.cpp

+16-9
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ QgsMarkerSymbolLayerV2::QgsMarkerSymbolLayerV2( bool locked )
173173
: QgsSymbolLayerV2( QgsSymbolV2::Marker, locked ), mSizeUnit( QgsSymbolV2::MM ), mOffsetUnit( QgsSymbolV2::MM ),
174174
mHorizontalAnchorPoint( HCenter ), mVerticalAnchorPoint( VCenter )
175175
{
176+
mOffsetExpression = NULL;
177+
mHorizontalAnchorExpression = NULL;
178+
mVerticalAnchorExpression = NULL;
176179
}
177180

178181
QgsLineSymbolLayerV2::QgsLineSymbolLayerV2( bool locked )
@@ -185,6 +188,13 @@ QgsFillSymbolLayerV2::QgsFillSymbolLayerV2( bool locked )
185188
{
186189
}
187190

191+
void QgsMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
192+
{
193+
mOffsetExpression = expression( "offset" );
194+
mHorizontalAnchorExpression = expression( "horizontal_anchor_point" );
195+
mVerticalAnchorExpression = expression( "vertical_anchor_point" );
196+
}
197+
188198
void QgsMarkerSymbolLayerV2::drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size )
189199
{
190200
startRender( context );
@@ -210,10 +220,9 @@ void QgsMarkerSymbolLayerV2::markerOffset( const QgsSymbolV2RenderContext& conte
210220
offsetX = mOffset.x();
211221
offsetY = mOffset.y();
212222

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

224233
HorizontalAnchorPoint horizontalAnchorPoint = mHorizontalAnchorPoint;
225234
VerticalAnchorPoint verticalAnchorPoint = mVerticalAnchorPoint;
226-
QgsExpression* horizontalAnchorExpression = expression( "horizontal_anchor_point" );
227-
if ( horizontalAnchorExpression )
235+
if ( mHorizontalAnchorExpression )
228236
{
229-
horizontalAnchorPoint = decodeHorizontalAnchorPoint( horizontalAnchorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
237+
horizontalAnchorPoint = decodeHorizontalAnchorPoint( mHorizontalAnchorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
230238
}
231-
QgsExpression* verticalAnchorExpression = expression( "vertical_anchor_point" );
232-
if ( verticalAnchorExpression )
239+
if ( mVerticalAnchorExpression )
233240
{
234-
verticalAnchorPoint = decodeVerticalAnchorPoint( verticalAnchorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
241+
verticalAnchorPoint = decodeVerticalAnchorPoint( mVerticalAnchorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() );
235242
}
236243

237244
//correct horizontal position according to anchor point

src/core/symbology-ng/qgssymbollayerv2.h

+6
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
146146
Bottom
147147
};
148148

149+
void startRender( QgsSymbolV2RenderContext& context );
150+
149151
virtual void renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ) = 0;
150152

151153
void drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size );
@@ -205,6 +207,10 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
205207
private:
206208
static QgsMarkerSymbolLayerV2::HorizontalAnchorPoint decodeHorizontalAnchorPoint( const QString& str );
207209
static QgsMarkerSymbolLayerV2::VerticalAnchorPoint decodeVerticalAnchorPoint( const QString& str );
210+
211+
QgsExpression* mOffsetExpression;
212+
QgsExpression* mHorizontalAnchorExpression;
213+
QgsExpression* mVerticalAnchorExpression;
208214
};
209215

210216
class CORE_EXPORT QgsLineSymbolLayerV2 : public QgsSymbolLayerV2

0 commit comments

Comments
 (0)