Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  textureproviderobserver.hpp   Sprache: C

 

/*****************************************************************************
 * Copyright (C) 2025 VLC authors and VideoLAN
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * ( at your option ) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifndef TEXTUREPROVIDEROBSERVER_HPP
#define TEXTUREPROVIDEROBSERVER_HPP

#include <QObject>
#include <QReadWriteLock>
#include <QPointer>
#include <QSize>
#include <QQuickItem>

class QSGTextureProvider;

// This utility class observes a texture provider and exposes its texture's properties
// so that they can be accessed in QML where texture introspection is not possible.
class TextureProviderObserver : public QObject
{
    Q_OBJECT

    // NOTE: source must be a texture provider item.
    // NOTE: If source's texture provider changes, it is required to re-set the property.
    Q_PROPERTY(const QQuickItem* source MEMBER m_source WRITE setSource NOTIFY sourceChanged FINAL)

    // WARNING: Texture properties are updated in the rendering thread.
    // WARNING: Individual properties do not necessarily reflect the same texture at any arbitrary time.
    //          In other words, properties are not updated atomically as a whole but independently
    //          once the source texture changes. It depends on when you are reading the properties,
    //          such that if you read properties before `updateTextureSize()` returns, the properties
    //          may be inconsistent with each other (some reflecting the old texture, some the new
    //          texture). This is done to reduce blocking the GUI thread from the rendering thread,
    //          which is a problem unlike vice versa, and is considered acceptable because sampling
    //          is supposed to be done periodically anyway (the sampling point must be chosen carefully
    //          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: If the source texture is a dynamic texture (such as an item layer), these properties are
    //       notified at most per frame, provided that `notifyAllChanges` is set. This is done to prevent
    //       event backlogging. If the source texture is not a dynamic texture, these are notified as soon
    //       as applicable, where in that case `notifyAllChanges` is not required to be set. The method
    //       `::sampleAndNotifyProperties()` may also be called to notify changes at an arbitrary time.
    //       It is guaranteed that notifications are emitted from the GUI thread, unless an arbitrary
    //       `sampleAndNotifyProperties()` call was made in a different thread. Note that if the texture
    //       is a dynamic texture and `notifyAllChanges` is set, the notifications will be signalled from
    //       the thread of the window of the source texture provider item, particularly during
    //       `QQuickWindow::afterAnimating()`, which is guaranteed to be GUI thread but not necessarily
    //       the thread of the items that use this observer. For that reason it is not recommended to
    //       use the observer for an item that belongs to the same window of the source texture provider
    //       item in such a case (texture is dynamic and `notifyAllChanges` is set). Also note that if
    //       the source texture is of `QSGDynamicTexture` type but is not meant to be dynamic (such as
    //       an item layer with `live: false`), it should ideally be provided as a hint to the observer
    //       observer by unsetting `notifyAllChanges`, so that it does not do sampling per frame. That
    //       being said, since event backlogging is still not possible, such benefit is minimal and
    //       should only be done if it does not hinder maintenance.
    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)
    Q_PROPERTY(qint64 comparisonKey READ comparisonKey NOTIFY comparisonKeyChanged 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
    //       connection (default), it may be queued in the receiver thread:
    Q_PROPERTY(bool hasAlphaChannel READ hasAlphaChannel NOTIFY hasAlphaChannelChanged FINAL)
    Q_PROPERTY(bool hasMipmaps READ hasMipmaps NOTIFY hasMipmapsChanged FINAL)
    Q_PROPERTY(bool isAtlasTexture READ isAtlasTexture NOTIFY isAtlasTextureChanged FINAL)
    Q_PROPERTY(bool isValid READ isValid NOTIFY isValidChanged FINAL) // whether a texture is provided or not
    Q_PROPERTY(bool isDynamic READ isDynamic NOTIFY isDynamicChanged FINAL) // whether the texture is `QSGDynamicTexture`

public:
    explicit TextureProviderObserver(QObject *parent = nullptr);

    void setSource(const QQuickItem* source, bool enforce = false);

    // The following are likely called in the QML/GUI thread.
    // QML/GUI thread can freely block the rendering thread to the extent the time is reasonable and a
    // fraction of `1/FPS`, because it is already throttled by v-sync (so it would just throttle less).
    QSize textureSize() const;
    QSize nativeTextureSize() const;
    qint64 comparisonKey() const;
    QRectF normalizedTextureSubRect() const;
    bool hasAlphaChannel() const;
    bool hasMipmaps() const;
    bool isAtlasTexture() const;
    bool isValid() const;
    bool isDynamic() const;

public slots:
    // This is mostly relevant for dynamic textures, since for static textures
    // notification is done regardless of sampling. This method is thread-safe.
    void sampleAndNotifyProperties();

signals:
    // Similar to property notify signals, if the texture is dynamic, this
    // signal is compressed and emitted at once once per frame from the GUI
    // thread. If the texture is not dynamic, it is not compressed and emitted
    // from the sg/rendering thread. You may use auto connection to connect
    // to this signal, because there is no risk for backlogging (static
    // textures are not expected to change rapidly).
    void textureChanged();

    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);
    void isValidChanged(bool);
    void isDynamicChanged(bool);
    void comparisonKeyChanged(qint64);

private slots:
    void updateProperties();
    void resetProperties(std::memory_order memoryOrder = std::memory_order_seq_cst);
    // This must be called from the same thread the source item lives:
    void adjustSampleAndNotifyConnection();

private:
    QPointer<const QQuickItem> m_source;
    QPointer<QSGTextureProvider> m_provider;
    QPointer<QQuickWindow> m_window;
    QMetaObject::Connection m_windowSampleAndNotifyPropertiesConnection;
    // It is not clear when `QSGTextureProvider::textureChanged()` can be signalled.
    // If it is only signalled during SG synchronization where Qt blocks the GUI thread,
    // we do not need explicit synchronization (with atomic, or mutex) here. If it can be
    // signalled at any time, we can still rely on SG synchronization (instead of explicit
    // synchronization) by waiting until the next synchronization, but the delay might be
    // more in that case. At the same time, the source might be living in a different window
    // where the SG synchronization would not be blocking the (GUI) thread where this
    // observer lives.

    std::atomic<bool> m_textureIsDynamic = false;
    std::atomic<bool> m_notifyAllChanges = true;
    std::atomic<QSize> m_textureSize {{}}; // invalid by default
    std::atomic<QSize> m_oldTextureSize {{}}; // invalid by default
    std::atomic<QSize> m_nativeTextureSize {{}}; // invalid by default
    std::atomic<QSize> m_oldNativeTextureSize {{}}; // invalid by default
    std::atomic<qint64> m_comparisonKey {-1};
    std::atomic<qint64> m_oldComparisonKey {-1};
    std::atomic<QRectF> m_normalizedTextureSubRect {{}}; // invalid by default
    std::atomic<QRectF> m_oldNormalizedTextureSubRect {{}}; // invalid by default

    std::atomic<bool> m_hasAlphaChannel = false;
    std::atomic<bool> m_hasMipmaps = false;
    std::atomic<bool> m_isAtlasTexture = false;
    std::atomic<bool> m_isValid = false;
    std::atomic<bool> m_pendingNotifyTextureChange = false;
};

#endif // TEXTUREPROVIDEROBSERVER_HPP

Messung
CHZG
9110010096

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104857
#Domains=418205