[vlc-commits] [Git][videolan/vlc][master] 5 commits: qt: prefer Format_ARGB32_Premultiplied to Format_ARGB32 in RoundImage

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Fri Apr 1 13:06:56 UTC 2022



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
f2df0011 by Fatih Uzunoglu at 2022-04-01T12:24:27+00:00
qt: prefer Format_ARGB32_Premultiplied to Format_ARGB32 in RoundImage

- - - - -
9cbeacfc by Fatih Uzunoglu at 2022-04-01T12:24:27+00:00
qt: handle case when radius is 0 in RoundImage

- - - - -
38c2a7ec by Fatih Uzunoglu at 2022-04-01T12:24:27+00:00
qt: avoid explicit QPainter calls in RoundImage

- - - - -
88c51859 by Fatih Uzunoglu at 2022-04-01T12:24:27+00:00
qt: remove getPath() from RoundImage

- - - - -
4333661c by Fatih Uzunoglu at 2022-04-01T12:24:27+00:00
qt: remove unnecessary member in RoundImage

- - - - -


2 changed files:

- modules/gui/qt/widgets/native/roundimage.cpp
- modules/gui/qt/widgets/native/roundimage.hpp


Changes:

=====================================
modules/gui/qt/widgets/native/roundimage.cpp
=====================================
@@ -39,6 +39,7 @@
 #include <QGuiApplication>
 #include <QSGImageNode>
 #include <QtQml>
+#include <QQmlFile>
 
 #ifdef QT_NETWORK_LIB
 #include <QNetworkAccessManager>
@@ -73,19 +74,12 @@ namespace
     // images are cached (result of RoundImageGenerator) with the cost calculated from QImage::sizeInBytes
     QCache<ImageCacheKey, QImage> imageCache(2 * 1024 * 1024); // 2 MiB
 
-    QString getPath(const QUrl &url)
-    {
-        QString path = url.isLocalFile() ? url.toLocalFile() : url.toString();
-        if (path.startsWith("qrc:///"))
-            path.replace(0, strlen("qrc:///"), ":/");
-        return path;
-    }
-
     std::unique_ptr<QIODevice> getReadable(const QUrl &url)
+    try
     {
-#ifdef QT_NETWORK_LIB
-        if (url.scheme() == "http" || url.scheme() == "https")
+        if (!QQmlFile::isLocalFile(url))
         {
+#ifdef QT_NETWORK_LIB
             QNetworkAccessManager networkMgr;
             networkMgr.setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
             auto reply = networkMgr.get(QNetworkRequest(url));
@@ -94,38 +88,33 @@ namespace
             loop.exec();
 
             if (reply->error() != QNetworkReply::NoError)
-            {
-                qDebug() << reply->errorString();
-                return {};
-            }
+                throw std::runtime_error(reply->errorString().toStdString());
 
-            class DataOwningBuffer : public QBuffer
+            class DataOwningBuffer : private QByteArray, public QBuffer
             {
             public:
-                DataOwningBuffer(const QByteArray &data) : m_data {data}
-                {
-                    setBuffer(&m_data);
-                }
-
-                ~DataOwningBuffer()
-                {
-                    close();
-                    setBuffer(nullptr);
-                }
-
-            private:
-                QByteArray m_data;
+                explicit DataOwningBuffer(const QByteArray &data)
+                    : QByteArray(data), QBuffer(this, nullptr) { }
             };
 
             auto file = std::make_unique<DataOwningBuffer>(reply->readAll());
             file->open(QIODevice::ReadOnly);
             return file;
-        }
+#else
+            throw std::runtime_error("Qt Network Library is not available!");
 #endif
-
-        auto file = std::make_unique<QFile>(getPath(url));
-        file->open(QIODevice::ReadOnly);
-        return file;
+        }
+        else
+        {
+            auto file = std::make_unique<QFile>(QQmlFile::urlToLocalFileOrQrc(url));
+            file->open(QIODevice::ReadOnly);
+            return file;
+        }
+    }
+    catch (const std::exception& error)
+    {
+        qWarning() << "Could not load source image:" << url << error.what();
+        return {};
     }
 }
 
@@ -157,7 +146,8 @@ QSGNode *RoundImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
             assert(window());
 
             QSGTexture* texture = window()->createTextureFromImage(m_roundImage,
-                static_cast<QQuickWindow::CreateTextureOptions>(QQuickWindow::TextureHasAlphaChannel |
+                static_cast<QQuickWindow::CreateTextureOptions>((Q_LIKELY(m_roundImage.hasAlphaChannel()) ? QQuickWindow::TextureHasAlphaChannel
+                                                                                                          : 0) |
                                                                 QQuickWindow::TextureCanUseAtlas));
 
             if (texture)
@@ -180,19 +170,10 @@ QSGNode *RoundImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
     return node;
 }
 
-void RoundImage::classBegin()
-{
-    QQuickItem::classBegin();
-
-    m_isComponentComplete = false;
-}
-
 void RoundImage::componentComplete()
 {
     QQuickItem::componentComplete();
 
-    Q_ASSERT(!m_isComponentComplete); // classBegin is not called?
-    m_isComponentComplete = true;
     if (!m_source.isEmpty())
         regenerateRoundImage();
 }
@@ -207,7 +188,7 @@ qreal RoundImage::radius() const
     return m_radius;
 }
 
-void RoundImage::setSource(QUrl source)
+void RoundImage::setSource(const QUrl& source)
 {
     if (m_source == source)
         return;
@@ -246,7 +227,7 @@ void RoundImage::setDPR(const qreal value)
 
 void RoundImage::regenerateRoundImage()
 {
-    if (!m_isComponentComplete || m_enqueuedGeneration)
+    if (!isComponentComplete() || m_enqueuedGeneration)
         return;
 
     m_roundImageGenerator.reset();
@@ -339,23 +320,28 @@ QImage RoundImage::RoundImageGenerator::execute()
     const QPointF alignedCenteredTopLeft {(size.width() - targetSize.width()) / 2., (size.height() - targetSize.height()) / 2.};
     sourceReader.setScaledSize(targetSize.toSize());
 
-    QImage target(width, height, QImage::Format_ARGB32);
+    if (Q_UNLIKELY(radius <= 0))
+    {
+        return sourceReader.read();
+    }
+
+    QImage target(width, height, QImage::Format_ARGB32_Premultiplied);
     if (target.isNull())
         return target;
 
     target.fill(Qt::transparent);
 
-    QPainter painter;
-    painter.begin(&target);
-    painter.setRenderHint(QPainter::Antialiasing, true);
-    painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
+    {
+        QPainter painter(&target);
+        painter.setRenderHint(QPainter::Antialiasing, true);
+        painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
 
-    QPainterPath path;
-    path.addRoundedRect(0, 0, width, height, radius, radius);
-    painter.setClipPath(path);
+        QPainterPath path;
+        path.addRoundedRect(0, 0, width, height, radius, radius);
+        painter.setClipPath(path);
 
-    painter.drawImage({alignedCenteredTopLeft, targetSize}, sourceReader.read());
-    painter.end();
+        painter.drawImage({alignedCenteredTopLeft, targetSize}, sourceReader.read());
+    }
 
     return target;
 }


=====================================
modules/gui/qt/widgets/native/roundimage.hpp
=====================================
@@ -43,20 +43,18 @@ class RoundImage : public QQuickItem
 public:
     RoundImage(QQuickItem *parent = nullptr);
 
-    void classBegin() override;
     void componentComplete() override;
 
     QUrl source() const;
     qreal radius() const;
 
 public slots:
-    void setSource(QUrl source);
+    void setSource(const QUrl& source);
     void setRadius(qreal radius);
 
 signals:
-    void sourceChanged(QUrl source);
-    void radiusChanged(int radius);
-    void sourceSizeChanged(QSizeF sourceSize);
+    void sourceChanged(const QUrl&);
+    void radiusChanged(qreal);
 
 protected:
     void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override;
@@ -90,7 +88,6 @@ private:
     TaskHandle<RoundImageGenerator> m_roundImageGenerator {};
 
     bool m_enqueuedGeneration = false;
-    bool m_isComponentComplete = true;
 };
 
 #endif



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/7ab09b01b3d462bbcd1b58747ee1606f3ad0eaf6...4333661cdf5dc769a6c1a64c4d953300edb1f7d0

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/7ab09b01b3d462bbcd1b58747ee1606f3ad0eaf6...4333661cdf5dc769a6c1a64c4d953300edb1f7d0
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