[vlc-commits] [Git][videolan/vlc][master] qt: fix threaded usage of QGraphicsScene pixmap painting

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sat Mar 5 20:49:35 UTC 2022



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
9ec6146c by Fatih Uzunoglu at 2022-03-05T19:52:30+00:00
qt: fix threaded usage of QGraphicsScene pixmap painting

- - - - -


2 changed files:

- modules/gui/qt/util/covergenerator.cpp
- modules/gui/qt/util/covergenerator.hpp


Changes:

=====================================
modules/gui/qt/util/covergenerator.cpp
=====================================
@@ -34,6 +34,11 @@
 #include <QGraphicsBlurEffect>
 #include <QUrl>
 
+// Qt private exported function
+QT_BEGIN_NAMESPACE
+extern void VLC_WEAK qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0);
+QT_END_NAMESPACE
+
 //-------------------------------------------------------------------------------------------------
 // Static variables
 
@@ -215,7 +220,7 @@ QString CoverGenerator::execute() /* override */
     painter.end();
 
     if (m_blur > 0)
-        blur(&image);
+        blur(image);
 
     image.save(fileName, "jpg");
 
@@ -320,32 +325,47 @@ void CoverGenerator::drawImage(QPainter & painter, const QString & fileName, con
 
 //-------------------------------------------------------------------------------------------------
 
-// FIXME: This implementation is not ideal and uses a dedicated QGraphicsScene.
-void CoverGenerator::blur(QImage * image)
+void CoverGenerator::blur(QImage& image)
 {
-    assert(image);
-
-    QGraphicsScene scene;
-
-    QGraphicsPixmapItem item(QPixmap::fromImage(*image));
+    if (Q_LIKELY(&qt_blurImage))
+    {
+        // A symbol is available for qt_blurImage()
+        // Exported function can be used directly within a separate thread:
+        qt_blurImage(image, 2.5 * (m_blur + 1), true);
+    }
+    else
+    {
+        const auto blurImage = [&]() {
+            QGraphicsScene scene;
 
-    QGraphicsBlurEffect effect;
+            QGraphicsPixmapItem item(QPixmap::fromImage(image));
 
-    effect.setBlurRadius(m_blur);
+            QGraphicsBlurEffect effect;
 
-    effect.setBlurHints(QGraphicsBlurEffect::QualityHint);
+            effect.setBlurRadius(m_blur);
 
-    item.setGraphicsEffect(&effect);
+            effect.setBlurHints(QGraphicsBlurEffect::QualityHint);
 
-    scene.addItem(&item);
+            item.setGraphicsEffect(&effect);
 
-    QImage result(image->size(), QImage::Format_ARGB32);
+            scene.addItem(&item);
 
-    QPainter painter(&result);
+            QPainter painter(&image);
 
-    scene.render(&painter);
+            scene.render(&painter);
+        };
 
-    *image = result;
+        if (qApp->thread() == QThread::currentThread())
+        {
+            blurImage();
+        }
+        else
+        {
+            // Not executing in Qt GUI thread, this is not supported.
+            // Block this thread, and blur the image in the GUI thread instead:
+            QMetaObject::invokeMethod(qApp, blurImage, Qt::BlockingQueuedConnection);
+        }
+    }
 }
 
 //-------------------------------------------------------------------------------------------------


=====================================
modules/gui/qt/util/covergenerator.hpp
=====================================
@@ -86,7 +86,7 @@ private: // Functions
 
     void drawImage(QPainter & painter, const QString & fileName, const QRect & rect);
 
-    void blur(QImage * image);
+    void blur(QImage &image);
 
     QString getPrefix(vlc_ml_parent_type type) const;
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/9ec6146c39f8fce14a7a2d07f08a42aecb27cba7

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/9ec6146c39f8fce14a7a2d07f08a42aecb27cba7
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list