18 static QHash<GraphicsBuffer *, TransactionDmaBufLocker *> lockers;
19 if (
auto it = lockers.find(buffer); it != lockers.end()) {
29 lockers[buffer] = locker;
30 QObject::connect(buffer, &QObject::destroyed, [buffer]() {
31 delete lockers.take(buffer);
37TransactionDmaBufLocker::TransactionDmaBufLocker(
const DmaBufAttributes *attributes)
39 for (
int i = 0; i < attributes->
planeCount; ++i) {
40 auto notifier =
new QSocketNotifier(attributes->
fd[i].get(), QSocketNotifier::Read);
41 notifier->setEnabled(
false);
42 connect(notifier, &QSocketNotifier::activated,
this, [
this, notifier]() {
43 notifier->setEnabled(
false);
44 m_pending.removeOne(notifier);
45 if (m_pending.isEmpty()) {
46 const auto transactions = m_transactions;
47 m_transactions.clear();
48 for (Transaction *transition : transactions) {
53 m_notifiers.emplace_back(notifier);
61 m_transactions.append(transition);
65bool TransactionDmaBufLocker::arm()
67 if (!m_pending.isEmpty()) {
70 for (
const auto ¬ifier : m_notifiers) {
71 if (!FileDescriptor::isReadable(notifier->socket())) {
72 notifier->setEnabled(
true);
73 m_pending.append(notifier.get());
76 return !m_pending.isEmpty();
79Transaction::Transaction()
83void Transaction::lock()
88void Transaction::unlock()
90 Q_ASSERT(m_locks > 0);
97bool Transaction::isReady()
const
103 return std::none_of(m_entries.cbegin(), m_entries.cend(), [](
const TransactionEntry &entry) {
104 return entry.previousTransaction;
111 if (entry.surface == surface) {
112 return entry.nextTransaction;
120 SurfaceState *pending = SurfaceInterfacePrivate::get(surface)->pending.get();
123 if (entry.surface == surface) {
132 auto state = std::make_unique<SurfaceState>();
138 .state = std::move(state),
145 if (entry.surface == surface) {
146 mutator(entry.state.get());
153 for (
size_t i = 0; i < other->m_entries.size(); ++i) {
154 m_entries.emplace_back(std::move(other->m_entries[i]));
156 other->m_entries.clear();
178static SurfaceInterface *mainSurface(SurfaceInterface *surface)
180 SubSurfaceInterface *subsurface = surface->subSurface();
187void Transaction::apply()
190 std::sort(m_entries.begin(), m_entries.end(), [](
const TransactionEntry &a,
const TransactionEntry &b) {
198 if (isAncestor(a.surface, b.surface)) {
201 if (isAncestor(b.surface, a.surface)) {
204 return mainSurface(a.surface) < mainSurface(b.surface);
207 for (TransactionEntry &entry : m_entries) {
209 SurfaceInterfacePrivate::get(entry.surface)->applyState(entry.state.get());
213 for (TransactionEntry &entry : m_entries) {
215 if (entry.surface->lastTransaction() ==
this) {
217 entry.surface->setLastTransaction(
nullptr);
219 entry.surface->setFirstTransaction(entry.nextTransaction);
223 if (entry.nextTransaction) {
224 for (TransactionEntry &otherEntry : entry.nextTransaction->m_entries) {
225 if (otherEntry.previousTransaction ==
this) {
226 otherEntry.previousTransaction =
nullptr;
230 entry.nextTransaction->tryApply();
237bool Transaction::tryApply()
246void Transaction::commit()
249 if (entry.state->bufferIsSet && entry.state->buffer) {
251 if (
auto locker = TransactionDmaBufLocker::get(entry.state->buffer)) {
256 if (entry.surface->firstTransaction()) {
257 Transaction *lastTransaction = entry.surface->lastTransaction();
259 if (lastEntry.surface == entry.surface) {
260 lastEntry.nextTransaction =
this;
264 entry.surface->setFirstTransaction(
this);
267 entry.previousTransaction = entry.surface->lastTransaction();
268 entry.surface->setLastTransaction(
this);
273 Q_EMIT entry.surface->stateStashed(entry.state->serial);
280#include "moc_transaction.cpp"
virtual const DmaBufAttributes * dmabufAttributes() const
SurfaceInterface * parentSurface() const
SurfaceInterface * mainSurface() const
Resource representing a wl_surface.
GraphicsBuffer * buffer() const
void setFirstTransaction(Transaction *transaction)
SubSurfaceInterface * subSurface() const
static TransactionDmaBufLocker * get(GraphicsBuffer *buffer)
std::array< FileDescriptor, 4 > fd
void mergeInto(SurfaceState *target)
QPointer< GraphicsBuffer > buffer
QPointer< SurfaceInterface > surface