File indexing completed on 2025-01-05 03:59:18

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2008 Torsten Rahn <tackat@kde.org>
0004 // SPDX-FileCopyrightText: 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
0005 // SPDX-FileCopyrightText: 2011, 2012 Bernahrd Beschow <bbeschow@cs.tu-berlin.de>
0006 //
0007 
0008 
0009 // Own
0010 #include "LayerManager.h"
0011 
0012 #include <QElapsedTimer>
0013 
0014 // Local dir
0015 #include "AbstractDataPlugin.h"
0016 #include "AbstractDataPluginItem.h"
0017 #include "GeoPainter.h"
0018 #include "RenderPlugin.h"
0019 #include "LayerInterface.h"
0020 #include "RenderState.h"
0021 
0022 #include "digikam_debug.h"
0023 
0024 namespace Marble
0025 {
0026 
0027 class Q_DECL_HIDDEN LayerManager::Private
0028 {
0029  public:
0030     Private(LayerManager *parent);
0031     ~Private();
0032 
0033     void updateVisibility( bool visible, const QString &nameId );
0034 
0035     LayerManager *const q;
0036 
0037     QList<RenderPlugin *> m_renderPlugins;
0038     QList<AbstractDataPlugin *> m_dataPlugins;
0039     QList<LayerInterface *> m_internalLayers;
0040 
0041     RenderState m_renderState;
0042 
0043     bool m_showBackground;
0044     bool m_showRuntimeTrace;
0045 };
0046 
0047 LayerManager::Private::Private(LayerManager *parent) :
0048     q(parent),
0049     m_renderPlugins(),
0050     m_showBackground(true),
0051     m_showRuntimeTrace(false)
0052 {
0053 }
0054 
0055 LayerManager::Private::~Private()
0056 {
0057 }
0058 
0059 void LayerManager::Private::updateVisibility( bool visible, const QString &nameId )
0060 {
0061     Q_EMIT q->visibilityChanged( nameId, visible );
0062 }
0063 
0064 
0065 LayerManager::LayerManager(QObject *parent) :
0066     QObject(parent),
0067     d(new Private(this))
0068 {
0069 }
0070 
0071 LayerManager::~LayerManager()
0072 {
0073     delete d;
0074 }
0075 
0076 bool LayerManager::showBackground() const
0077 {
0078     return d->m_showBackground;
0079 }
0080 
0081 bool LayerManager::showRuntimeTrace() const
0082 {
0083     return d->m_showRuntimeTrace;
0084 }
0085 
0086 void LayerManager::addRenderPlugin(RenderPlugin *renderPlugin)
0087 {
0088     d->m_renderPlugins.append(renderPlugin);
0089 
0090     QObject::connect(renderPlugin, SIGNAL(settingsChanged(QString)),
0091                      this, SIGNAL(pluginSettingsChanged()));
0092     QObject::connect(renderPlugin, SIGNAL(repaintNeeded(QRegion)),
0093                      this, SIGNAL(repaintNeeded(QRegion)));
0094     QObject::connect(renderPlugin, SIGNAL(visibilityChanged(bool,QString)),
0095                      this, SLOT(updateVisibility(bool,QString)));
0096 
0097     // get data plugins
0098     AbstractDataPlugin *const dataPlugin = qobject_cast<AbstractDataPlugin *>(renderPlugin);
0099     if(dataPlugin) {
0100         d->m_dataPlugins.append(dataPlugin);
0101     }
0102 }
0103 
0104 QList<AbstractDataPlugin *> LayerManager::dataPlugins() const
0105 {
0106     return d->m_dataPlugins;
0107 }
0108 
0109 QList<AbstractDataPluginItem *> LayerManager::whichItemAt( const QPoint& curpos ) const
0110 {
0111     QList<AbstractDataPluginItem *> itemList;
0112 
0113     for( auto *plugin: d->m_dataPlugins ) {
0114         itemList.append( plugin->whichItemAt( curpos ) );
0115     }
0116     return itemList;
0117 }
0118 
0119 void LayerManager::renderLayers( GeoPainter *painter, ViewportParams *viewport )
0120 {
0121     d->m_renderState = RenderState(QStringLiteral("Marble"));
0122     QElapsedTimer totalTime;
0123     totalTime.start();
0124 
0125     QStringList renderPositions;
0126 
0127     if ( d->m_showBackground ) {
0128         renderPositions
0129         << QStringLiteral("STARS")
0130         << QStringLiteral("BEHIND_TARGET");
0131     }
0132 
0133     renderPositions
0134         << QStringLiteral("SURFACE")
0135         << QStringLiteral("HOVERS_ABOVE_SURFACE")
0136         << QStringLiteral("GRATICULE")
0137         << QStringLiteral("PLACEMARKS")
0138         << QStringLiteral("ATMOSPHERE")
0139         << QStringLiteral("ORBIT")
0140         << QStringLiteral("ALWAYS_ON_TOP")
0141         << QStringLiteral("FLOAT_ITEM")
0142         << QStringLiteral("USER_TOOLS");
0143 
0144     QStringList traceList;
0145     for( const auto& renderPosition: renderPositions ) {
0146         QList<LayerInterface*> layers;
0147 
0148         // collect all RenderPlugins of current renderPosition
0149         for( auto *renderPlugin: d->m_renderPlugins ) {
0150             if ( renderPlugin && renderPlugin->renderPosition().contains( renderPosition ) ) {
0151                 if ( renderPlugin->enabled() && renderPlugin->visible() ) {
0152                     if ( !renderPlugin->isInitialized() ) {
0153                         renderPlugin->initialize();
0154                         Q_EMIT renderPluginInitialized( renderPlugin );
0155                     }
0156                     layers.push_back( renderPlugin );
0157                 }
0158             }
0159         }
0160 
0161         // collect all internal LayerInterfaces of current renderPosition
0162         for( auto *layer: d->m_internalLayers ) {
0163             if ( layer && layer->renderPosition().contains( renderPosition ) ) {
0164                 layers.push_back( layer );
0165             }
0166         }
0167 
0168         // sort them according to their zValue()s
0169         std::sort( layers.begin(), layers.end(), [] ( const LayerInterface * const one, const LayerInterface * const two ) -> bool {
0170             Q_ASSERT( one && two );
0171             return one->zValue() < two->zValue();
0172         } );
0173 
0174         // render the layers of the current renderPosition
0175         QElapsedTimer timer;
0176         for( auto *layer: layers ) {
0177             timer.start();
0178             layer->render( painter, viewport, renderPosition, nullptr );
0179             d->m_renderState.addChild( layer->renderState() );
0180             traceList.append( QString::fromUtf8("%2 ms %3").arg( timer.elapsed(),3 ).arg( layer->runtimeTrace() ) );
0181         }
0182     }
0183 
0184     if ( d->m_showRuntimeTrace ) {
0185         const int totalElapsed = totalTime.elapsed();
0186         const int fps = 1000.0/totalElapsed;
0187         traceList.append( QString::fromUtf8( "Total: %1 ms (%2 fps)" ).arg( totalElapsed, 3 ).arg( fps ) );
0188 
0189         painter->save();
0190         painter->setBackgroundMode( Qt::OpaqueMode );
0191         painter->setBackground( Qt::gray );
0192         painter->setFont( QFont( QStringLiteral("Sans Serif"), 10, QFont::Bold ) );
0193 
0194         int i=0;
0195         int const top = 150;
0196         int const lineHeight = painter->fontMetrics().height();
0197         for ( const auto &text: traceList ) {
0198             painter->setPen( Qt::black );
0199             painter->drawText( QPoint(10,top+1+lineHeight*i), text );
0200             painter->setPen( Qt::white );
0201             painter->drawText( QPoint(9,top+lineHeight*i), text );
0202             ++i;
0203         }
0204         painter->restore();
0205     }
0206 }
0207 
0208 void LayerManager::setShowBackground( bool show )
0209 {
0210     d->m_showBackground = show;
0211 }
0212 
0213 void LayerManager::setShowRuntimeTrace( bool show )
0214 {
0215     d->m_showRuntimeTrace = show;
0216 }
0217 
0218 void LayerManager::addLayer(LayerInterface *layer)
0219 {
0220     if (!d->m_internalLayers.contains(layer)) {
0221         d->m_internalLayers.push_back(layer);
0222     }
0223 }
0224 
0225 void LayerManager::removeLayer(LayerInterface *layer)
0226 {
0227     d->m_internalLayers.removeAll(layer);
0228 }
0229 
0230 QList<LayerInterface *> LayerManager::internalLayers() const
0231 {
0232     return d->m_internalLayers;
0233 }
0234 
0235 RenderState LayerManager::renderState() const
0236 {
0237     return d->m_renderState;
0238 }
0239 
0240 }
0241 
0242 #include "moc_LayerManager.cpp"