File indexing completed on 2024-05-19 05:32:46

0001 /*
0002     SPDX-FileCopyrightText: 2023 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #pragma once
0008 
0009 #include "core/graphicsbuffer.h"
0010 
0011 #include <QPointer>
0012 
0013 #include <functional>
0014 #include <memory>
0015 #include <vector>
0016 
0017 namespace KWin
0018 {
0019 
0020 class SurfaceInterface;
0021 struct SurfaceState;
0022 class Transaction;
0023 
0024 /**
0025  * The TransactionEntry type represents a log entry in a Transaction.
0026  */
0027 struct TransactionEntry
0028 {
0029     /**
0030      * The surface that is going to be affected by the transaction. Might be
0031      * \c null if the surface has been destroyed while the transaction is still
0032      * not ready.
0033      */
0034     QPointer<SurfaceInterface> surface;
0035 
0036     /**
0037      * The previous transaction that this transaction depends on.
0038      */
0039     Transaction *previousTransaction = nullptr;
0040 
0041     /**
0042      * Next transaction that is going to affect the surface.
0043      */
0044     Transaction *nextTransaction = nullptr;
0045 
0046     /**
0047      * Graphics buffer reference to prevent it from being destroyed.
0048      */
0049     GraphicsBufferRef buffer;
0050 
0051     /**
0052      * The surface state that is going to be applied.
0053      */
0054     std::unique_ptr<SurfaceState> state;
0055 };
0056 
0057 /**
0058  * The Transaction type provides a way to commit the pending state of one or more surfaces atomically.
0059  */
0060 class KWIN_EXPORT Transaction
0061 {
0062 public:
0063     Transaction();
0064 
0065     /**
0066      * Locks the transaction. While the transaction is locked, it cannot be applied.
0067      */
0068     void lock();
0069 
0070     /**
0071      * Unlocks the transaction.
0072      */
0073     void unlock();
0074 
0075     /**
0076      * Returns \c true if this transaction can be applied, i.e. all its dependencies are resolved;
0077      * otherwise returns \c false.
0078      */
0079     bool isReady() const;
0080 
0081     /**
0082      * Returns the next transaction for the specified \a surface. If this transaction does
0083      * not affect the given surface, \c null is returned.
0084      */
0085     Transaction *next(SurfaceInterface *surface) const;
0086 
0087     /**
0088      * Adds the specified \a surface to this transaction. The transaction will move the pending
0089      * surface state and apply it when it's possible.
0090      */
0091     void add(SurfaceInterface *surface);
0092 
0093     /**
0094      * Amends already committed state.
0095      */
0096     void amend(SurfaceInterface *surface, std::function<void(SurfaceState *state)> mutator);
0097 
0098     /**
0099      * Merge the given \a other transaction with this transaction. The other transaction must be
0100      * uncommitted.
0101      */
0102     void merge(Transaction *other);
0103 
0104     /**
0105      * Commits the transaction. Note that the transaction may be applied later if there are previous
0106      * transactions that have not been applied yet or if the transaction is locked.
0107      *
0108      * The commit() function takes the ownership of the transaction. The transaction will be destroyed
0109      * when it is applied.
0110      */
0111     void commit();
0112 
0113 private:
0114     void apply();
0115     bool tryApply();
0116 
0117     std::vector<TransactionEntry> m_entries;
0118     int m_locks = 0;
0119 };
0120 
0121 } // namespace KWin