wayland: Desynchronize transactions of the same client

At the moment transactions from the same client are applied in the
commit order even if the trasactions affect unrelated surfaces.

This patch desynchronizes transactions affecting unrelated surfaces.

With this, if a client updates two surfaces (as an example, Firefox with
two windows) and one of its surfaces takes longer to render, the other
surface is not going to be slowed down.

Another nice thing is that it removes client from Transaction, which
might be potentially useful to the Workspace for coordinated resize or
something.
This commit is contained in:
Vlad Zahorodnii 2023-09-12 13:00:24 +03:00
parent 4b6c83be12
commit 00c12aa766
4 changed files with 6 additions and 73 deletions

View file

@ -26,8 +26,6 @@ public:
uid_t user = 0;
gid_t group = 0;
QString executablePath;
Transaction *firstTransaction = nullptr;
Transaction *lastTransaction = nullptr;
qreal scaleOverride = 1.0;
private:
@ -158,26 +156,6 @@ qreal ClientConnection::scaleOverride() const
return d->scaleOverride;
}
Transaction *ClientConnection::firstTransaction() const
{
return d->firstTransaction;
}
void ClientConnection::setFirstTransaction(Transaction *transaction)
{
d->firstTransaction = transaction;
}
Transaction *ClientConnection::lastTransaction() const
{
return d->lastTransaction;
}
void ClientConnection::setLastTransaction(Transaction *transaction)
{
d->lastTransaction = transaction;
}
}
#include "moc_clientconnection.cpp"

View file

@ -19,7 +19,6 @@ namespace KWaylandServer
{
class ClientConnectionPrivate;
class Display;
class Transaction;
/**
* @brief Convenient Class which represents a wl_client.
@ -126,18 +125,6 @@ public:
void setScaleOverride(qreal scaleOverride);
qreal scaleOverride() const;
/**
* The first committed transaction that belongs to this client.
*/
Transaction *firstTransaction() const;
void setFirstTransaction(Transaction *transaction);
/**
* The last committed transaction that belongs to this client.
*/
Transaction *lastTransaction() const;
void setLastTransaction(Transaction *transaction);
Q_SIGNALS:
/**
* This signal is emitted when the client is about to be destroyed.

View file

@ -6,7 +6,6 @@
#include "wayland/transaction.h"
#include "utils/filedescriptor.h"
#include "wayland/clientconnection.h"
#include "wayland/subcompositor_interface.h"
#include "wayland/surface_interface_p.h"
#include "wayland/transaction_p.h"
@ -108,12 +107,7 @@ bool Transaction::isReady() const
}
}
return m_client->firstTransaction() == this;
}
Transaction *Transaction::next() const
{
return m_nextTransaction;
return true;
}
Transaction *Transaction::next(SurfaceInterface *surface) const
@ -217,26 +211,19 @@ void Transaction::apply()
for (TransactionEntry &entry : m_entries) {
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 {
entry.surface->setFirstTransaction(entry.nextTransaction);
Transaction *nextTransaction = entry.nextTransaction;
entry.surface->setFirstTransaction(nextTransaction);
nextTransaction->tryApply();
}
}
if (m_client->lastTransaction() == this) {
m_client->setFirstTransaction(nullptr);
m_client->setLastTransaction(nullptr);
} else {
m_client->setFirstTransaction(m_nextTransaction);
}
if (m_nextTransaction) {
m_nextTransaction->tryApply();
}
delete this;
}
@ -252,10 +239,6 @@ bool Transaction::tryApply()
void Transaction::commit()
{
for (TransactionEntry &entry : m_entries) {
if (!m_client) {
m_client = entry.surface->client();
}
if (entry.state->bufferIsSet && entry.state->buffer) {
// Avoid applying the transaction until all graphics buffers have become idle.
if (auto locker = TransactionDmaBufLocker::get(entry.state->buffer)) {
@ -277,13 +260,6 @@ void Transaction::commit()
entry.surface->setLastTransaction(this);
}
if (m_client->firstTransaction()) {
m_client->lastTransaction()->m_nextTransaction = this;
} else {
m_client->setFirstTransaction(this);
}
m_client->setLastTransaction(this);
if (!tryApply()) {
for (const TransactionEntry &entry : m_entries) {
Q_EMIT entry.surface->stateStashed(entry.state->serial);

View file

@ -15,7 +15,6 @@
namespace KWaylandServer
{
class ClientConnection;
class SurfaceInterface;
class SurfaceState;
class Transaction;
@ -70,11 +69,6 @@ public:
*/
bool isReady() const;
/**
* Returns the next transaction that should be applied after this transaction.
*/
Transaction *next() const;
/**
* Returns the next transaction for the specified \a surface. If this transaction does
* not affect the given surface, \c null is returned.
@ -116,8 +110,6 @@ private:
void apply();
bool tryApply();
ClientConnection *m_client = nullptr;
Transaction *m_nextTransaction = nullptr;
std::vector<TransactionEntry> m_entries;
int m_locks = 0;
};