1 /***************************************************************************
2                               qgsmaprendererjobproxy.cpp
3                               --------------------------
4     begin                : January 2017
5     copyright            : (C) 2017 by Paul Blottiere
6     email                : paul dot blottiere at oslandia dot com
7 ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "qgsmaprendererjobproxy.h"
19 
20 #include "qgsmessagelog.h"
21 #include "qgsmaprendererparalleljob.h"
22 #include "qgsmaprenderercustompainterjob.h"
23 #include "qgsapplication.h"
24 
25 namespace QgsWms
26 {
27 
QgsMapRendererJobProxy(bool parallelRendering,int maxThreads,QgsFeatureFilterProvider * featureFilterProvider)28   QgsMapRendererJobProxy::QgsMapRendererJobProxy(
29     bool parallelRendering
30     , int maxThreads
31     , QgsFeatureFilterProvider *featureFilterProvider
32   )
33     :
34     mParallelRendering( parallelRendering )
35     , mFeatureFilterProvider( featureFilterProvider )
36   {
37 #ifndef HAVE_SERVER_PYTHON_PLUGINS
38     Q_UNUSED( mFeatureFilterProvider )
39 #endif
40     if ( mParallelRendering )
41     {
42       QgsApplication::setMaxThreads( maxThreads );
43       QgsMessageLog::logMessage( QStringLiteral( "Parallel rendering activated with %1 threads" ).arg( maxThreads ), QStringLiteral( "server" ), Qgis::MessageLevel::Info );
44     }
45     else
46     {
47       QgsMessageLog::logMessage( QStringLiteral( "Parallel rendering deactivated" ), QStringLiteral( "server" ), Qgis::MessageLevel::Info );
48     }
49   }
50 
render(const QgsMapSettings & mapSettings,QImage * image)51   void QgsMapRendererJobProxy::render( const QgsMapSettings &mapSettings, QImage *image )
52   {
53     if ( mParallelRendering )
54     {
55       QgsMapRendererParallelJob renderJob( mapSettings );
56 #ifdef HAVE_SERVER_PYTHON_PLUGINS
57       renderJob.setFeatureFilterProvider( mFeatureFilterProvider );
58 #endif
59       renderJob.start();
60 
61       // Allows the main thread to manage blocking call coming from rendering
62       // threads (see discussion in https://github.com/qgis/QGIS/issues/26819).
63       QEventLoop loop;
64       QObject::connect( &renderJob, &QgsMapRendererParallelJob::finished, &loop, &QEventLoop::quit );
65       loop.exec();
66 
67       renderJob.waitForFinished();
68       *image = renderJob.renderedImage();
69       mPainter.reset( new QPainter( image ) );
70 
71       mErrors = renderJob.errors();
72     }
73     else
74     {
75       mPainter.reset( new QPainter( image ) );
76       QgsMapRendererCustomPainterJob renderJob( mapSettings, mPainter.get() );
77 #ifdef HAVE_SERVER_PYTHON_PLUGINS
78       renderJob.setFeatureFilterProvider( mFeatureFilterProvider );
79 #endif
80       renderJob.renderSynchronously();
81       mErrors = renderJob.errors();
82     }
83   }
84 
takePainter()85   QPainter *QgsMapRendererJobProxy::takePainter()
86   {
87     return mPainter.release();
88   }
89 } // namespace qgsws
90