wayland: Keep transaction entries for deleted surfaces
If a transaction entry is removed, the graphics buffer reference will be dropped and it's possible that the TransactionDmaBufLocker is going to be destroyed as well. If that happens, the transaction may remain in the locked state.
This commit is contained in:
parent
693fa8a968
commit
df8ddb609b
3 changed files with 23 additions and 26 deletions
|
@ -407,10 +407,6 @@ SurfaceInterface::~SurfaceInterface()
|
|||
{
|
||||
delete d->subsurface.transaction;
|
||||
d->subsurface.transaction = nullptr;
|
||||
|
||||
for (auto transaction = d->firstTransaction; transaction; transaction = transaction->next(this)) {
|
||||
transaction->remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceRole *SurfaceInterface::role() const
|
||||
|
|
|
@ -103,6 +103,9 @@ bool Transaction::isReady() const
|
|||
}
|
||||
|
||||
for (const TransactionEntry &entry : m_entries) {
|
||||
if (!entry.surface) {
|
||||
continue;
|
||||
}
|
||||
if (entry.surface->firstTransaction() != this) {
|
||||
return false;
|
||||
}
|
||||
|
@ -145,13 +148,6 @@ void Transaction::add(SurfaceInterface *surface)
|
|||
});
|
||||
}
|
||||
|
||||
void Transaction::remove(SurfaceInterface *surface)
|
||||
{
|
||||
std::erase_if(m_entries, [surface](const TransactionEntry &entry) {
|
||||
return entry.surface == surface;
|
||||
});
|
||||
}
|
||||
|
||||
void Transaction::amend(SurfaceInterface *surface, std::function<void(SurfaceState *)> mutator)
|
||||
{
|
||||
for (TransactionEntry &entry : m_entries) {
|
||||
|
@ -211,17 +207,23 @@ void Transaction::apply()
|
|||
});
|
||||
|
||||
for (TransactionEntry &entry : m_entries) {
|
||||
SurfaceInterfacePrivate::get(entry.surface)->applyState(entry.state.get());
|
||||
if (entry.surface) {
|
||||
SurfaceInterfacePrivate::get(entry.surface)->applyState(entry.state.get());
|
||||
}
|
||||
}
|
||||
|
||||
for (TransactionEntry &entry : m_entries) {
|
||||
if (entry.surface->lastTransaction() == this) {
|
||||
entry.surface->setFirstTransaction(nullptr);
|
||||
entry.surface->setLastTransaction(nullptr);
|
||||
} else {
|
||||
Transaction *nextTransaction = entry.nextTransaction;
|
||||
entry.surface->setFirstTransaction(nextTransaction);
|
||||
nextTransaction->tryApply();
|
||||
if (entry.surface) {
|
||||
if (entry.surface->lastTransaction() == this) {
|
||||
entry.surface->setFirstTransaction(nullptr);
|
||||
entry.surface->setLastTransaction(nullptr);
|
||||
} else {
|
||||
entry.surface->setFirstTransaction(entry.nextTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
if (entry.nextTransaction) {
|
||||
entry.nextTransaction->tryApply();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include "core/graphicsbuffer.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
@ -25,9 +27,11 @@ class Transaction;
|
|||
struct TransactionEntry
|
||||
{
|
||||
/**
|
||||
* The surface that is going to be affected by the transaction.
|
||||
* The surface that is going to be affected by the transaction. Might be
|
||||
* \c null if the surface has been destroyed while the transaction is still
|
||||
* not ready.
|
||||
*/
|
||||
SurfaceInterface *surface = nullptr;
|
||||
QPointer<SurfaceInterface> surface;
|
||||
|
||||
/**
|
||||
* Next transaction that is going to affect the surface.
|
||||
|
@ -81,11 +85,6 @@ public:
|
|||
*/
|
||||
void add(SurfaceInterface *surface);
|
||||
|
||||
/**
|
||||
* Removes the specified \a surface from this transaction.
|
||||
*/
|
||||
void remove(SurfaceInterface *surface);
|
||||
|
||||
/**
|
||||
* Amends already committed state.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue