diff --git a/src/EngineController.cpp b/src/EngineController.cpp --- a/src/EngineController.cpp +++ b/src/EngineController.cpp @@ -54,6 +54,9 @@ #include +#include + + // for slotMetaDataChanged() typedef QPair FieldPair; @@ -1242,7 +1245,10 @@ << "-" << ( track->album() ? track->album()->name() : QString( "[no album]" ) ) << "-" << track->name() << "," << playedFraction << ")"; - track->finishedPlaying( playedFraction ); + + // Track::finishedPlaying is thread-safe and can take a long time to finish. + std::thread thread( &Meta::Track::finishedPlaying, track, playedFraction ); + thread.detach(); } void diff --git a/src/context/applets/currenttrack/plugin/CurrentEngine.cpp b/src/context/applets/currenttrack/plugin/CurrentEngine.cpp --- a/src/context/applets/currenttrack/plugin/CurrentEngine.cpp +++ b/src/context/applets/currenttrack/plugin/CurrentEngine.cpp @@ -42,14 +42,15 @@ { EngineController* engine = The::engineController(); + // Connect queued to reduce interface stuttering. connect( engine, &EngineController::trackPlaying, - this, &CurrentEngine::slotTrackChanged ); + this, &CurrentEngine::slotTrackChanged, Qt::QueuedConnection ); connect( engine, &EngineController::stopped, - this, &CurrentEngine::stopped ); + this, &CurrentEngine::stopped, Qt::QueuedConnection ); connect( engine, &EngineController::trackMetadataChanged, - this, &CurrentEngine::slotTrackMetadataChanged ); + this, &CurrentEngine::slotTrackMetadataChanged, Qt::QueuedConnection ); connect( engine, &EngineController::albumMetadataChanged, - this, &CurrentEngine::slotAlbumMetadataChanged ); + this, &CurrentEngine::slotAlbumMetadataChanged, Qt::QueuedConnection ); } CurrentEngine::~CurrentEngine() diff --git a/src/core-impl/collections/db/sql/SqlMeta.cpp b/src/core-impl/collections/db/sql/SqlMeta.cpp --- a/src/core-impl/collections/db/sql/SqlMeta.cpp +++ b/src/core-impl/collections/db/sql/SqlMeta.cpp @@ -59,6 +59,9 @@ #include #include +#include + + // additional constants namespace Meta { @@ -1607,7 +1610,8 @@ if( size > 1 && size < 1000 ) { image = image.scaled( size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - image.save( cachedImagePath, "PNG" ); + std::thread thread( QOverload::of( &QImage::save ), image, cachedImagePath, "PNG", -1 ); + thread.detach(); } return image; @@ -1663,7 +1667,8 @@ while( QFile(path).exists() ) path += '_'; // not that nice but it shouldn't happen that often. - image.save( path, "JPG" ); + std::thread thread( QOverload::of( &QImage::save ), image, path, "JPG", -1 ); + thread.detach(); setImage( path ); locker.unlock(); diff --git a/src/core-impl/collections/db/sql/SqlScanResultProcessor.cpp b/src/core-impl/collections/db/sql/SqlScanResultProcessor.cpp --- a/src/core-impl/collections/db/sql/SqlScanResultProcessor.cpp +++ b/src/core-impl/collections/db/sql/SqlScanResultProcessor.cpp @@ -33,6 +33,7 @@ #include +#include #include SqlScanResultProcessor::SqlScanResultProcessor( GenericScanManager* manager, @@ -94,13 +95,17 @@ void SqlScanResultProcessor::blockUpdates() { + DEBUG_BLOCK + m_collection->blockUpdatedSignal(); m_collection->registry()->blockDatabaseUpdate(); } void SqlScanResultProcessor::unblockUpdates() { + DEBUG_BLOCK + m_collection->registry()->unblockDatabaseUpdate(); m_collection->unblockUpdatedSignal(); } @@ -627,6 +632,8 @@ void SqlScanResultProcessor::urlsCacheInit() { + DEBUG_BLOCK + auto storage = m_collection->sqlStorage(); QString query = QString( "SELECT id, deviceid, rpath, directory, uniqueid FROM urls;"); @@ -660,6 +667,8 @@ } urlsCacheInsert( entry ); + + QAbstractEventDispatcher::instance()->processEvents( QEventLoop::AllEvents ); } } diff --git a/src/core/meta/support/MetaUtility.cpp b/src/core/meta/support/MetaUtility.cpp --- a/src/core/meta/support/MetaUtility.cpp +++ b/src/core/meta/support/MetaUtility.cpp @@ -113,6 +113,8 @@ QVariantMap Meta::Field::mprisMapFromTrack( const Meta::TrackPtr track ) { + DEBUG_BLOCK + QVariantMap map; if( track ) { @@ -130,10 +132,11 @@ if( track->album()->hasAlbumArtist() && !track->album()->albumArtist()->name().isEmpty() ) map[ "albumartist" ] = track->album()->albumArtist()->name(); - QImage image = track->album()->image(); QUrl url = track->album()->imageLocation(); - if ( url.isValid() && !url.isLocalFile() ) { + if ( url.isValid() && !url.isLocalFile() ) + { // embedded id? Request a version to be put in the cache + QImage image = track->album()->image(); int width = track->album()->image().width(); url = track->album()->imageLocation( width ); debug() << "MPRIS: New location for width" << width << "is" << url; @@ -173,6 +176,8 @@ QVariantMap Meta::Field::mpris20MapFromTrack( const Meta::TrackPtr track ) { + DEBUG_BLOCK + QVariantMap map; if( track ) { @@ -189,12 +194,12 @@ Meta::ConstStatisticsPtr statistics = track->statistics(); if( album ) { - QImage image = album->image(); QUrl url = album->imageLocation(); debug() << "MPRIS2: Album image location is" << url; if ( url.isValid() && !url.isLocalFile() ) { // embedded id? Request a version to be put in the cache + QImage image = album->image(); int width = album->image().width(); url = album->imageLocation( width ); debug() << "MPRIS2: New location for width" << width << "is" << url; diff --git a/src/covermanager/CoverCache.cpp b/src/covermanager/CoverCache.cpp --- a/src/covermanager/CoverCache.cpp +++ b/src/covermanager/CoverCache.cpp @@ -25,11 +25,13 @@ #include #include #include +#include #include -#include #include +#include + CoverCache* CoverCache::s_instance = 0; CoverCache* @@ -115,7 +117,8 @@ { const QPixmap orgPixmap( QStandardPaths::locate( QStandardPaths::GenericDataLocation, "amarok/images/nocover.png" ) ); pixmap = orgPixmap.scaled( size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation ); - pixmap.save( cacheCoverDir.filePath( noCoverKey ), "PNG" ); + std::thread thread( QOverload::of( &QPixmap::save ), pixmap, cacheCoverDir.filePath( noCoverKey ), "PNG", -1 ); + thread.detach(); } QPixmapCache::insert( noCoverKey, pixmap ); return pixmap; diff --git a/src/services/ServiceAlbumCoverDownloader.cpp b/src/services/ServiceAlbumCoverDownloader.cpp --- a/src/services/ServiceAlbumCoverDownloader.cpp +++ b/src/services/ServiceAlbumCoverDownloader.cpp @@ -81,7 +81,8 @@ else if( m_hasFetchedCover && !m_cover.isNull() ) { QImage image( m_cover.scaled( size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation ) ); - image.save( cacheCoverPath, "PNG" ); + std::thread thread( QOverload::of( &QImage::save ), image, cacheCoverPath, "PNG", -1 ); + thread.detach(); return image; } else if( !m_isFetchingCover && !coverUrl().isEmpty() )