[vlc-commits] [Git][videolan/vlc][master] 7 commits: qml: make sure the layer is gone when it is not used in `ArtistTopBanner`
Steve Lhomme (@robUx4)
gitlab at videolan.org
Sun Oct 5 10:14:54 UTC 2025
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
81af16b6 by Fatih Uzunoglu at 2025-10-05T09:59:24+00:00
qml: make sure the layer is gone when it is not used in `ArtistTopBanner`
This is for the switching case, once the layer is created it would remain,
so setting the `sourceItem` to null while `live` is enabled should help
with this.
Instead of creating the layer once and keeping it around, I believe it
makes more sense to destroy it when it is not used, and re-create when
necessary.
- - - - -
40049d8e by Fatih Uzunoglu at 2025-10-05T09:59:24+00:00
qt: use weak pointer for the target texture in `QSGTextureView`
This is useful for these situations:
- Target is gone for any reason.
- Target is gone, but its provider did not report it. This is
for the cases where the view is not driven by its default
provider counterpart, `QSGTextureViewProvider`.
- - - - -
b851692d by Fatih Uzunoglu at 2025-10-05T09:59:24+00:00
qt: fix unable to reset sub-rect in texture view
- - - - -
b4e36c5b by Fatih Uzunoglu at 2025-10-05T09:59:24+00:00
qt: introduce `QSGTextureView::requestDetachFromAtlas()`
This allows detaching from the atlas at appropriate time,
which is useful because calling `removedFromAtlas()`
directly may be problematic without an update batch.
- - - - -
abfe098d by Fatih Uzunoglu at 2025-10-05T09:59:24+00:00
qt: introduce property `detachAtlasTextures` in `TextureProviderItem`
This boolean property allows detaching the target textures from the
atlas when applicable. As the comment describes, this is useful in
certain situations, such as making use of wrapping.
- - - - -
afc55821 by Fatih Uzunoglu at 2025-10-05T09:59:24+00:00
qml: get rid of the layer used for tiling in `ArtistTopBanner`
Do tiling at sampler level than layer level, thanks to
the texture view. This allows us to save video memory.
- - - - -
fdcb6f07 by Fatih Uzunoglu at 2025-10-05T09:59:24+00:00
qml: do not display the effect during initialization in `ArtistTopBanner`
- - - - -
5 changed files:
- modules/gui/qt/medialibrary/qml/ArtistTopBanner.qml
- modules/gui/qt/util/qsgtextureview.cpp
- modules/gui/qt/util/qsgtextureview.hpp
- modules/gui/qt/widgets/native/textureprovideritem.cpp
- modules/gui/qt/widgets/native/textureprovideritem.hpp
Changes:
=====================================
modules/gui/qt/medialibrary/qml/ArtistTopBanner.qml
=====================================
@@ -77,7 +77,7 @@ FocusScope {
Item {
anchors.fill: background
- visible: (GraphicsInfo.shaderType === GraphicsInfo.RhiShader)
+ visible: (GraphicsInfo.shaderType === GraphicsInfo.RhiShader) && (root.artist.id) // do not display the effect during initialization
// This blur effect does not create an implicit layer that is updated
// each time the size changes. The source texture is static, so the blur
@@ -92,15 +92,19 @@ FocusScope {
// NOTE: No need to disable `live`, as this uses two pass mode so there is no video memory saving benefit.
- // If source image is tiled, layering is necessary:
- readonly property bool sourceNeedsLayering: (background.fillMode === Image.Tile)
+ readonly property bool sourceNeedsTiling: (background.fillMode === Image.Tile)
readonly property real aspectRatio: (background.implicitHeight / background.implicitWidth)
- height: sourceNeedsLayering ? background.height : (aspectRatio * width)
+ height: sourceNeedsTiling ? background.height : (aspectRatio * width)
source: textureProviderItem
+ // Instead of clipping in the parent, denote the viewport here so we both
+ // do not need to clip the excess, and also save significant video memory:
+ viewportRect: !blurEffect.sourceNeedsLayering ? Qt.rect((width - parent.width) / 2, (height - parent.height) / 2, parent.width, parent.height)
+ : Qt.rect(0, 0, 0, 0)
+
Widgets.TextureProviderItem {
id: textureProviderItem
@@ -110,23 +114,17 @@ FocusScope {
// we can have an indirection here through `TextureProviderItem`.
// This is totally acceptable as there is virtually no overhead.
- source: blurEffect.sourceNeedsLayering ? backgroundLayer : background
- }
-
- // Instead of clipping in the parent, denote the viewport here so we both
- // do not need to clip the excess, and also save significant video memory:
- viewportRect: !blurEffect.sourceNeedsLayering ? Qt.rect((width - parent.width) / 2, (height - parent.height) / 2, parent.width, parent.height)
- : Qt.rect(0, 0, 0, 0)
+ source: background
- ShaderEffectSource {
- id: backgroundLayer
+ detachAtlasTextures: blurEffect.sourceNeedsTiling
- sourceItem: background
+ horizontalWrapMode: blurEffect.sourceNeedsTiling ? Widgets.TextureProviderItem.Repeat : Widgets.TextureProviderItem.ClampToEdge
+ verticalWrapMode: blurEffect.sourceNeedsTiling ? Widgets.TextureProviderItem.Repeat : Widgets.TextureProviderItem.ClampToEdge
- // We hope that Qt does not create the layer unless this is actually used as
- // texture provider (it is already invisible). GammaRay tells that this is
- // already the case (I can not access the texture).
- visible: false
+ textureSubRect: blurEffect.sourceNeedsTiling ? Qt.rect(blurEffect.width / 8,
+ blurEffect.height / 8,
+ blurEffect.width * 1.25,
+ blurEffect.height * 1.25) : undefined
}
// Strong blurring is not wanted here:
=====================================
modules/gui/qt/util/qsgtextureview.cpp
=====================================
@@ -112,9 +112,6 @@ void QSGTextureView::setRect(const QRect &rect)
if (m_rect == rect)
return;
- if (!rect.isValid())
- return;
-
m_rect = rect;
// We need the source texture in order to calculate the normal rect.
@@ -122,7 +119,10 @@ void QSGTextureView::setRect(const QRect &rect)
// later in `normalizedTextureSubRect()`.
if (m_texture)
{
- adjustNormalRect();
+ if (m_rect.isValid())
+ adjustNormalRect();
+ else
+ m_normalRect.reset();
emit updateRequested();
}
else
@@ -284,7 +284,20 @@ QSGTexture *QSGTextureView::removedFromAtlas(QRhiResourceUpdateBatch *batch) con
void QSGTextureView::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
{
if (m_texture)
+ {
+ if (m_detachFromAtlasPending)
+ {
+ if (isAtlasTexture())
+ {
+ const auto oldTexture = m_texture;
+ if (removedFromAtlas(resourceUpdates))
+ qDebug() << this << ": Detached" << oldTexture << "from the atlas, and re-targeted to" << m_texture;
+ }
+ m_detachFromAtlasPending = false;
+ }
+
m_texture->commitTextureOperations(rhi, resourceUpdates);
+ }
}
bool QSGTextureView::updateTexture()
@@ -306,3 +319,7 @@ bool QSGTextureView::updateTexture()
return ret;
}
+void QSGTextureView::requestDetachFromAtlas()
+{
+ m_detachFromAtlasPending = true;
+}
=====================================
modules/gui/qt/util/qsgtextureview.hpp
=====================================
@@ -26,10 +26,11 @@ class QSGTextureView : public QSGDynamicTexture
{
Q_OBJECT
- QSGTexture* m_texture = nullptr;
+ QPointer<QSGTexture> m_texture;
QRect m_rect;
mutable std::optional<QRectF> m_normalRect;
mutable bool m_normalRectChanged = false;
+ bool m_detachFromAtlasPending = false;
private slots:
bool adjustNormalRect() const;
@@ -75,6 +76,9 @@ public:
bool updateTexture() override;
+ // Detaches from atlas (when applicable) upon the next `commitTextureOperations()` call:
+ void requestDetachFromAtlas();
+
signals:
void updateRequested();
};
=====================================
modules/gui/qt/widgets/native/textureprovideritem.cpp
=====================================
@@ -83,11 +83,6 @@ QSGTextureProvider *TextureProviderItem::textureProvider() const
}
};
- const auto adjustRect = [provider = m_textureProvider](const QRect& rect) {
- if (rect.isValid())
- provider->setRect(rect);
- };
-
const auto synchronizeState = [weakThis = QPointer(this), provider = m_textureProvider]() {
if (Q_UNLIKELY(!weakThis))
return;
@@ -97,11 +92,14 @@ QSGTextureProvider *TextureProviderItem::textureProvider() const
provider->setAnisotropyLevel(weakThis->m_anisotropyLevel);
provider->setHorizontalWrapMode(weakThis->m_horizontalWrapMode);
provider->setVerticalWrapMode(weakThis->m_verticalWrapMode);
+
+ if (weakThis->m_detachAtlasTextures)
+ provider->requestDetachFromAtlas();
};
// These are going to be queued when necessary:
connect(this, &TextureProviderItem::sourceChanged, m_textureProvider, adjustSource);
- connect(this, &TextureProviderItem::rectChanged, m_textureProvider, adjustRect);
+ connect(this, &TextureProviderItem::rectChanged, m_textureProvider, &QSGTextureViewProvider::setRect);
connect(this, &TextureProviderItem::filteringChanged, m_textureProvider, &QSGTextureViewProvider::setFiltering);
connect(this, &TextureProviderItem::mipmapFilteringChanged, m_textureProvider, &QSGTextureViewProvider::setMipmapFiltering);
@@ -109,12 +107,18 @@ QSGTextureProvider *TextureProviderItem::textureProvider() const
connect(this, &TextureProviderItem::horizontalWrapModeChanged, m_textureProvider, &QSGTextureViewProvider::setHorizontalWrapMode);
connect(this, &TextureProviderItem::verticalWrapModeChanged, m_textureProvider, &QSGTextureViewProvider::setVerticalWrapMode);
+ connect(this, &TextureProviderItem::detachAtlasTexturesChanged, m_textureProvider, [provider = m_textureProvider](bool detach) {
+ if (detach)
+ provider->requestDetachFromAtlas();
+ });
+
// When the target texture changes, the texture view may reset its state, so we need to synchronize in that case:
connect(m_textureProvider, &QSGTextureProvider::textureChanged, m_textureProvider, synchronizeState); // Executed in texture provider's thread
// Initial adjustments:
adjustSource(m_source);
- adjustRect(m_rect);
+ if (m_rect.isValid())
+ m_textureProvider->setRect(m_rect);
synchronizeState();
}
return m_textureProvider;
@@ -264,3 +268,8 @@ void QSGTextureViewProvider::setVerticalWrapMode(QSGTexture::WrapMode vwrap)
m_textureView.setVerticalWrapMode(vwrap);
emit textureChanged();
}
+
+void QSGTextureViewProvider::requestDetachFromAtlas()
+{
+ m_textureView.requestDetachFromAtlas();
+}
=====================================
modules/gui/qt/widgets/native/textureprovideritem.hpp
=====================================
@@ -49,6 +49,8 @@ public:
void setAnisotropyLevel(QSGTexture::AnisotropyLevel level);
void setHorizontalWrapMode(QSGTexture::WrapMode hwrap);
void setVerticalWrapMode(QSGTexture::WrapMode vwrap);
+
+ void requestDetachFromAtlas();
};
class TextureProviderItem : public QQuickItem
@@ -62,8 +64,9 @@ class TextureProviderItem : public QQuickItem
// sub-texture (such as a texture in the atlas), wrapping would only be applicable outside
// the boundaries of the whole texture and not the source sub-texture, and not considering
// this may expose irrelevant parts of the atlas (this means that wrap mode is effectively
- // useless for sub- or atlas textures).
+ // useless for sub- or atlas textures). In such a case, `detachAtlasTextures` can be used.
Q_PROPERTY(QRect textureSubRect MEMBER m_rect NOTIFY rectChanged RESET resetTextureSubRect FINAL)
+ Q_PROPERTY(bool detachAtlasTextures MEMBER m_detachAtlasTextures NOTIFY detachAtlasTexturesChanged FINAL)
Q_PROPERTY(QSGTexture::AnisotropyLevel anisotropyLevel MEMBER m_anisotropyLevel NOTIFY anisotropyLevelChanged FINAL)
Q_PROPERTY(QSGTexture::WrapMode horizontalWrapMode MEMBER m_horizontalWrapMode NOTIFY horizontalWrapModeChanged FINAL)
@@ -122,6 +125,8 @@ signals:
void horizontalWrapModeChanged(QSGTexture::WrapMode);
void verticalWrapModeChanged(QSGTexture::WrapMode);
+ void detachAtlasTexturesChanged(bool);
+
protected:
void releaseResources() override;
@@ -138,6 +143,7 @@ private:
// When there are mip maps, no mip map filtering should be fine (unlike no mip maps with mip map filtering):
// But we want to have mip map filtering by default if the texture has mip maps (if not, it won't be respected):
std::atomic<QSGTexture::Filtering> m_mipmapFiltering = QSGTexture::Linear;
+ std::atomic<bool> m_detachAtlasTextures = false;
};
#endif // TEXTUREPROVIDERITEM_HPP
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8be3f74f504f7e782f43e8215f38ff1dd034e6ac...fdcb6f07789b6873594c2fd736dcb06e0e184370
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/8be3f74f504f7e782f43e8215f38ff1dd034e6ac...fdcb6f07789b6873594c2fd736dcb06e0e184370
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