[vlc-commits] [Git][videolan/vlc][master] qt: use scene graph to render RoundImage
François Cartegnie (@fcartegnie)
gitlab at videolan.org
Sun Jan 9 12:36:23 UTC 2022
François Cartegnie pushed to branch master at VideoLAN / VLC
Commits:
76379ba0 by Fatih Uzunoglu at 2022-01-09T11:53:29+00:00
qt: use scene graph to render 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
=====================================
@@ -37,6 +37,8 @@
#include <QPainterPath>
#include <QQuickWindow>
#include <QGuiApplication>
+#include <QSGImageNode>
+#include <QtQml>
#ifdef QT_NETWORK_LIB
#include <QNetworkAccessManager>
@@ -121,7 +123,7 @@ namespace
}
}
-RoundImage::RoundImage(QQuickItem *parent) : QQuickPaintedItem {parent}
+RoundImage::RoundImage(QQuickItem *parent) : QQuickItem {parent}
{
if (window() || qGuiApp)
setDPR(window() ? window()->devicePixelRatio() : qGuiApp->devicePixelRatio());
@@ -130,30 +132,62 @@ RoundImage::RoundImage(QQuickItem *parent) : QQuickPaintedItem {parent}
connect(this, &QQuickItem::widthChanged, this, &RoundImage::regenerateRoundImage);
}
-void RoundImage::paint(QPainter *painter)
+QSGNode *RoundImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
- if (m_roundImage.isNull())
- return;
- painter->drawImage(QPointF {0., 0.}, m_roundImage, m_roundImage.rect());
+ auto node = static_cast<QSGImageNode *>(oldNode);
+
+ if (!node)
+ {
+ assert(window());
+ node = window()->createImageNode();
+ assert(node);
+ node->setOwnsTexture(true);
+ }
+
+ if (m_dirty)
+ {
+ if (!m_roundImage.isNull())
+ {
+ assert(window());
+
+ QSGTexture* texture = window()->createTextureFromImage(m_roundImage,
+ QQuickWindow::TextureHasAlphaChannel);
+
+ if (texture)
+ {
+ // No need to delete the old texture manually as it is owned by the node.
+ node->setTexture(texture);
+ node->markDirty(QSGNode::DirtyMaterial);
+ }
+ else
+ {
+ qmlWarning(this) << "Could not generate texture from " << m_roundImage;
+ }
+ }
+
+ m_dirty = false;
+ }
+
+ node->setRect(boundingRect());
+
+ return node;
}
void RoundImage::classBegin()
{
- QQuickPaintedItem::classBegin();
+ QQuickItem::classBegin();
m_isComponentComplete = false;
}
void RoundImage::componentComplete()
{
- QQuickPaintedItem::componentComplete();
+ QQuickItem::componentComplete();
Q_ASSERT(!m_isComponentComplete); // classBegin is not called?
m_isComponentComplete = true;
if (!m_source.isEmpty())
regenerateRoundImage();
- else
- m_roundImage = {};
}
QUrl RoundImage::source() const
@@ -191,7 +225,7 @@ void RoundImage::itemChange(QQuickItem::ItemChange change, const QQuickItem::Ite
if (change == QQuickItem::ItemDevicePixelRatioHasChanged)
setDPR(value.realValue);
- QQuickPaintedItem::itemChange(change, value);
+ QQuickItem::itemChange(change, value);
}
void RoundImage::setDPR(const qreal value)
@@ -224,6 +258,8 @@ void RoundImage::regenerateRoundImage()
if (auto image = imageCache.object(key)) // should only by called in mainthread
{
m_roundImage = *image;
+ m_dirty = true;
+ setFlag(ItemHasContents, true);
update();
return;
}
@@ -233,12 +269,28 @@ void RoundImage::regenerateRoundImage()
m_roundImageGenerator.reset(new RoundImageGenerator(m_source, scaleWidth, scaledHeight, scaledRadius));
connect(m_roundImageGenerator.get(), &BaseAsyncTask::result, this, [this, key]()
{
- m_roundImage = m_roundImageGenerator->takeResult();
- m_roundImage.setDevicePixelRatio(m_dpr);
+ const auto image = new QImage(m_roundImageGenerator->takeResult());
+
m_roundImageGenerator.reset();
- if (!m_roundImage.isNull())
- imageCache.insert(key, new QImage(m_roundImage), m_roundImage.sizeInBytes());
+ if (!image->isNull())
+ {
+ image->setDevicePixelRatio(m_dpr);
+
+ imageCache.insert(key, image, image->sizeInBytes());
+
+ setFlag(ItemHasContents, true);
+
+ m_roundImage = *image;
+
+ m_dirty = true;
+ }
+ else
+ {
+ delete image;
+ m_dirty = false;
+ setFlag(ItemHasContents, false);
+ }
update();
});
=====================================
modules/gui/qt/widgets/native/roundimage.hpp
=====================================
@@ -28,10 +28,10 @@
#include "util/asynctask.hpp"
#include <QImage>
-#include <QQuickPaintedItem>
+#include <QQuickItem>
#include <QUrl>
-class RoundImage : public QQuickPaintedItem
+class RoundImage : public QQuickItem
{
Q_OBJECT
@@ -43,8 +43,6 @@ class RoundImage : public QQuickPaintedItem
public:
RoundImage(QQuickItem *parent = nullptr);
- void paint(QPainter *painter) override;
-
void classBegin() override;
void componentComplete() override;
@@ -62,6 +60,7 @@ signals:
protected:
void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override;
+ QSGNode* updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) override;
private:
class RoundImageGenerator : public AsyncTask<QImage>
@@ -84,7 +83,10 @@ private:
QUrl m_source;
qreal m_radius = 0.0;
qreal m_dpr = 1.0; // device pixel ratio
+
QImage m_roundImage;
+ bool m_dirty = false;
+
TaskHandle<RoundImageGenerator> m_roundImageGenerator {};
bool m_enqueuedGeneration = false;
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/76379ba010a5c081bbaa93aed5274b772423a81d
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/76379ba010a5c081bbaa93aed5274b772423a81d
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list