File tree 4 files changed +60
-0
lines changed
4 files changed +60
-0
lines changed Original file line number Diff line number Diff line change @@ -17,4 +17,15 @@ class QgsPluginLayer : QgsMapLayer
17
17
//! (defult implementation returns nothing)
18
18
//! @note Added in v2.1
19
19
virtual QgsLegendSymbologyList legendSymbologyItems( const QSize& iconSize );
20
+
21
+ /** Return new instance of QgsMapLayerRenderer that will be used for rendering of given context
22
+ *
23
+ * The default implementation returns map layer renderer which just calls draw().
24
+ * This may work, but it is unsafe for multi-threaded rendering because of the run
25
+ * conditions that may happen (e.g. something is changed in the layer while it is
26
+ * being rendered).
27
+ *
28
+ * @note added in 2.1
29
+ */
30
+ virtual QgsMapLayerRenderer* createMapRenderer( QgsRenderContext& rendererContext ) /Factory/;
20
31
};
Original file line number Diff line number Diff line change 14
14
***************************************************************************/
15
15
#include " qgspluginlayer.h"
16
16
17
+ #include " qgsmaplayerrenderer.h"
18
+
17
19
QgsPluginLayer::QgsPluginLayer ( QString layerType, QString layerName )
18
20
: QgsMapLayer( PluginLayer, layerName ), mPluginLayerType( layerType )
19
21
{
@@ -34,3 +36,28 @@ QgsLegendSymbologyList QgsPluginLayer::legendSymbologyItems( const QSize& iconSi
34
36
Q_UNUSED ( iconSize );
35
37
return QgsLegendSymbologyList ();
36
38
}
39
+
40
+ /* * Fallback layer renderer implementation for layer that do not support map renderer yet. */
41
+ class QgsPluginLayerRenderer : public QgsMapLayerRenderer
42
+ {
43
+ public:
44
+ QgsPluginLayerRenderer ( QgsPluginLayer* layer, QgsRenderContext& rendererContext )
45
+ : QgsMapLayerRenderer( layer->id () )
46
+ , mLayer( layer )
47
+ , mRendererContext( rendererContext )
48
+ {}
49
+
50
+ virtual bool render ()
51
+ {
52
+ return mLayer ->draw ( mRendererContext );
53
+ }
54
+
55
+ protected:
56
+ QgsPluginLayer* mLayer ;
57
+ QgsRenderContext& mRendererContext ;
58
+ };
59
+
60
+ QgsMapLayerRenderer* QgsPluginLayer::createMapRenderer ( QgsRenderContext& rendererContext )
61
+ {
62
+ return new QgsPluginLayerRenderer ( this , rendererContext );
63
+ }
Original file line number Diff line number Diff line change @@ -46,6 +46,17 @@ class CORE_EXPORT QgsPluginLayer : public QgsMapLayer
46
46
// ! @note Added in v2.1
47
47
virtual QgsLegendSymbologyList legendSymbologyItems ( const QSize& iconSize );
48
48
49
+ /* * Return new instance of QgsMapLayerRenderer that will be used for rendering of given context
50
+ *
51
+ * The default implementation returns map layer renderer which just calls draw().
52
+ * This may work, but it is unsafe for multi-threaded rendering because of the run
53
+ * conditions that may happen (e.g. something is changed in the layer while it is
54
+ * being rendered).
55
+ *
56
+ * @note added in 2.1
57
+ */
58
+ virtual QgsMapLayerRenderer* createMapRenderer ( QgsRenderContext& rendererContext );
59
+
49
60
protected:
50
61
QString mPluginLayerType ;
51
62
};
Original file line number Diff line number Diff line change 33
33
#include < QStringList>
34
34
#include < QDir>
35
35
36
+ PyThreadState* _mainState;
36
37
37
38
QgsPythonUtilsImpl::QgsPythonUtilsImpl ()
38
39
{
@@ -53,6 +54,9 @@ void QgsPythonUtilsImpl::initPython( QgisInterface* interface )
53
54
// initialize python
54
55
Py_Initialize ();
55
56
57
+ // initialize threading AND acquire GIL
58
+ PyEval_InitThreads ();
59
+
56
60
mPythonEnabled = true ;
57
61
58
62
mMainModule = PyImport_AddModule ( " __main__" ); // borrowed reference
@@ -167,6 +171,13 @@ void QgsPythonUtilsImpl::initPython( QgisInterface* interface )
167
171
168
172
QString startuppath = homePythonPath () + " + \" /startup.py\" " ;
169
173
runString ( " if os.path.exists(" + startuppath + " ): from startup import *\n " );
174
+
175
+ // release GIL!
176
+ // Later on, we acquire GIL just before doing some Python calls and
177
+ // release GIL again when the work with Python API is done.
178
+ // (i.e. there must be PyGILState_Ensure + PyGILState_Release pair
179
+ // around any calls to Python API, otherwise we may segfault!)
180
+ _mainState = PyEval_SaveThread ();
170
181
}
171
182
172
183
void QgsPythonUtilsImpl::exitPython ()
You can’t perform that action at this time.
0 commit comments