Browse Source

qt: introduce `notifyAllChanges` property in `TextureProviderObserver`

When `true` (by default `false`), all properties are notified on change.

This property may be set to `true` when the source is a static texture.
It is strongly discouraged to set it `true` for rapidly changing cases,
such as when the source is a layer, since if the connections are queued,
they can easily backlog when the texture changes rapidly (such as with
resize).
mmdevice-clean/8
Fatih Uzunoglu 6 months ago
committed by Steve Lhomme
parent
commit
416fe28d1a
  1. 63
      modules/gui/qt/util/textureproviderobserver.cpp
  2. 14
      modules/gui/qt/util/textureproviderobserver.hpp

63
modules/gui/qt/util/textureproviderobserver.cpp

@ -173,6 +173,8 @@ void TextureProviderObserver::updateProperties()
if (m_provider)
{
const bool notifyAllChanges = m_notifyAllChanges.load(memoryOrder);
if (const auto texture = m_provider->texture())
{
{
@ -180,24 +182,54 @@ void TextureProviderObserver::updateProperties()
// SG texture size:
const auto textureSize = texture->textureSize();
m_textureSize.store(textureSize, memoryOrder);
if (notifyAllChanges)
{
if (m_textureSize.exchange(textureSize, memoryOrder) != textureSize)
emit textureSizeChanged(textureSize);
}
else
{
m_textureSize.store(textureSize, memoryOrder);
}
{
// Native texture size
const auto legacyUpdateNativeTextureSize = [&]() {
const auto ntsr = texture->normalizedTextureSubRect();
m_nativeTextureSize.store({static_cast<int>(textureSize.width() / ntsr.width()),
static_cast<int>(textureSize.height() / ntsr.height())},
memoryOrder);
const QSize size = {static_cast<int>(textureSize.width() / ntsr.width()),
static_cast<int>(textureSize.height() / ntsr.height())};
if (notifyAllChanges)
{
if (m_nativeTextureSize.exchange(size, memoryOrder) != size)
emit nativeTextureSizeChanged(size);
}
else
{
m_nativeTextureSize.store(size, memoryOrder);
}
};
#ifdef RHI_HEADER_AVAILABLE
const QRhiTexture* const rhiTexture = texture->rhiTexture();
if (Q_LIKELY(rhiTexture))
m_nativeTextureSize.store(rhiTexture->pixelSize(), memoryOrder);
{
const QSize size = rhiTexture->pixelSize();
if (notifyAllChanges)
{
if (m_nativeTextureSize.exchange(size, memoryOrder) != size)
emit nativeTextureSizeChanged(size);
}
else
{
m_nativeTextureSize.store(size, memoryOrder);
}
}
else
{
legacyUpdateNativeTextureSize();
}
#else
legacyUpdateNativeTextureSize();
#endif
@ -208,7 +240,15 @@ void TextureProviderObserver::updateProperties()
// Normal rect
const QRectF& normalizedTextureSubRect = texture->normalizedTextureSubRect();
m_normalizedTextureSubRect.store(normalizedTextureSubRect, memoryOrder);
if (notifyAllChanges)
{
if (m_normalizedTextureSubRect.exchange(normalizedTextureSubRect, memoryOrder) != normalizedTextureSubRect)
emit normalizedTextureSubRectChanged(normalizedTextureSubRect);
}
else
{
m_normalizedTextureSubRect.store(normalizedTextureSubRect, memoryOrder);
}
}
{
@ -255,9 +295,14 @@ void TextureProviderObserver::updateProperties()
void TextureProviderObserver::resetProperties(std::memory_order memoryOrder)
{
m_textureSize.store({}, memoryOrder);
m_nativeTextureSize.store({}, memoryOrder);
m_normalizedTextureSubRect.store({}, memoryOrder);
if (m_textureSize.exchange({}, memoryOrder) != QSize())
emit textureSizeChanged({});
if (m_nativeTextureSize.exchange({}, memoryOrder) != QSize())
emit nativeTextureSizeChanged({});
if (m_normalizedTextureSubRect.exchange({}, memoryOrder) != QRectF())
emit normalizedTextureSubRectChanged({});
if (m_hasAlphaChannel.exchange(false, memoryOrder))
emit hasAlphaChannelChanged(false);

14
modules/gui/qt/util/textureproviderobserver.hpp

@ -47,14 +47,15 @@ class TextureProviderObserver : public QObject
// to not conflict with the updates, if the properties must reflect the immediately up-to-date
// texture and the properties change each frame, as otherwise it might end up in a
// "forever chase"), so by the time the sampling is done the properties should be consistent.
// NOTE: These properties do not provide notify signal, dynamic textures such as layer may
// NOTE: By default these properties are not notified, as dynamic textures such as layer may
// change rapidly (even though throttled by v-sync in the rendering thread), and if
// such signal is connected to a receiver that lives in the GUI thread, the queued
// invocations can easily backlog. Similar to the high precision timer, we moved
// away from event based approach in favor of sampling based approach here.
Q_PROPERTY(QSize textureSize READ textureSize FINAL) // Scene graph texture size
Q_PROPERTY(QSize nativeTextureSize READ nativeTextureSize FINAL) // Native texture size (e.g. for atlas textures, the atlas size)
Q_PROPERTY(QRectF normalizedTextureSubRect READ normalizedTextureSubRect FINAL)
Q_PROPERTY(bool notifyAllChanges MEMBER m_notifyAllChanges NOTIFY notifyAllChangesChanged FINAL)
Q_PROPERTY(QSize textureSize READ textureSize NOTIFY textureSizeChanged FINAL) // Scene graph texture size
Q_PROPERTY(QSize nativeTextureSize READ nativeTextureSize NOTIFY nativeTextureSizeChanged FINAL) // Native texture size (e.g. for atlas textures, the atlas size)
Q_PROPERTY(QRectF normalizedTextureSubRect READ normalizedTextureSubRect NOTIFY normalizedTextureSubRectChanged FINAL)
// NOTE: Since it is not expected that these properties change rapidly, they have notify signals.
// These signals may be emitted in the rendering thread, thus if the connection is auto
@ -83,7 +84,11 @@ public:
bool isValid() const;
signals:
void notifyAllChangesChanged();
void sourceChanged();
void textureSizeChanged(const QSize&);
void nativeTextureSizeChanged(const QSize&);
void normalizedTextureSubRectChanged(const QRectF&);
void hasAlphaChannelChanged(bool);
void hasMipmapsChanged(bool);
void isAtlasTextureChanged(bool);
@ -107,6 +112,7 @@ private:
// where the SG synchronization would not be blocking the (GUI) thread where this
// observer lives.
std::atomic<bool> m_notifyAllChanges = false;
std::atomic<QSize> m_textureSize {{}}; // invalid by default
std::atomic<QSize> m_nativeTextureSize {{}}; // invalid by default
std::atomic<qint64> m_comparisonKey {-1};

Loading…
Cancel
Save