File indexing completed on 2024-04-21 03:49:38

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