summaryrefslogtreecommitdiff
path: root/src/protocols
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2025-10-06 23:44:47 +0100
committerVaxry <vaxry@vaxry.net>2025-10-06 23:44:47 +0100
commitdc72259a5443116e892c49e37552ca5f82525ca6 (patch)
treea5a5b41ea5111564eba17a6b1262352550f53857 /src/protocols
parent02cda6bebf327e85c8b238961ce0514a66b92709 (diff)
core/compositor: revert make wl_surface::frame follow pending states (#11896)
This reverts commit 17e77e0407bebd5d24521012ee1d04b156d6b9f4. Reverted due to severe performance degradation due to accumulating frame callbacks
Diffstat (limited to 'src/protocols')
-rw-r--r--src/protocols/core/Compositor.cpp108
-rw-r--r--src/protocols/core/Compositor.hpp19
-rw-r--r--src/protocols/types/SurfaceState.cpp9
-rw-r--r--src/protocols/types/SurfaceState.hpp5
4 files changed, 49 insertions, 92 deletions
diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp
index 955ba5ca..484df21f 100644
--- a/src/protocols/core/Compositor.cpp
+++ b/src/protocols/core/Compositor.cpp
@@ -27,20 +27,16 @@ class CDefaultSurfaceRole : public ISurfaceRole {
}
};
-CWLCallbackResource::CWLCallbackResource(SP<CWlCallback>&& resource_) : m_resource(std::move(resource_)) {
+CWLCallbackResource::CWLCallbackResource(UP<CWlCallback>&& resource_) : m_resource(std::move(resource_)) {
;
}
bool CWLCallbackResource::good() {
- return m_resource && m_resource->resource();
+ return m_resource->resource();
}
void CWLCallbackResource::send(const Time::steady_tp& now) {
- if (!good())
- return;
-
m_resource->sendDone(Time::millis(now));
- m_resource.reset();
}
CWLRegionResource::CWLRegionResource(SP<CWlRegion> resource_) : m_resource(resource_) {
@@ -131,16 +127,17 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : m_resource(re
return;
}
- // null buffer attached
- if (!m_pending.buffer && !m_pending.texture && m_pending.updated.bits.buffer) {
+ if ((!m_pending.updated.bits.buffer) || // no new buffer attached
+ (!m_pending.buffer && !m_pending.texture) // null buffer attached
+ ) {
commitState(m_pending);
- // remove any pending states.
- while (!m_pendingStates.empty()) {
- m_pendingStates.pop();
+ if (!m_pending.buffer && !m_pending.texture) {
+ // null buffer attached, remove any pending states.
+ while (!m_pendingStates.empty()) {
+ m_pendingStates.pop();
+ }
}
-
- m_pendingWaiting = false;
m_pending.reset();
return;
}
@@ -149,9 +146,36 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : m_resource(re
const auto& state = m_pendingStates.emplace(makeUnique<SSurfaceState>(m_pending));
m_pending.reset();
- if (!m_pendingWaiting) {
- m_pendingWaiting = true;
- scheduleState(state);
+ auto whenReadable = [this, surf = m_self, state = WP<SSurfaceState>(m_pendingStates.back())] {
+ if (!surf || state.expired())
+ return;
+
+ while (!m_pendingStates.empty() && m_pendingStates.front() != state) {
+ commitState(*m_pendingStates.front());
+ m_pendingStates.pop();
+ }
+
+ commitState(*m_pendingStates.front());
+ m_pendingStates.pop();
+ };
+
+ if (state->updated.bits.acquire) {
+ // wait on acquire point for this surface, from explicit sync protocol
+ state->acquire.addWaiter(std::move(whenReadable));
+ } else if (state->buffer->isSynchronous()) {
+ // synchronous (shm) buffers can be read immediately
+ whenReadable();
+ } else if (state->buffer->type() == Aquamarine::BUFFER_TYPE_DMABUF && state->buffer->dmabuf().success) {
+ // async buffer and is dmabuf, then we can wait on implicit fences
+ auto syncFd = dc<CDMABuffer*>(state->buffer.m_buffer.get())->exportSyncFile();
+
+ if (syncFd.isValid())
+ g_pEventLoopManager->doOnReadable(std::move(syncFd), std::move(whenReadable));
+ else
+ whenReadable();
+ } else {
+ Debug::log(ERR, "BUG THIS: wl_surface.commit: no acquire, non-dmabuf, async buffer, needs wait... this shouldn't happen");
+ whenReadable();
}
});
@@ -215,10 +239,7 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : m_resource(re
m_pending.opaque = RG->m_region;
});
- m_resource->setFrame([this](CWlSurface* r, uint32_t id) {
- m_pending.updated.bits.frame = true;
- m_pending.callbacks.emplace_back(makeShared<CWLCallbackResource>(makeShared<CWlCallback>(m_client, 1, id)));
- });
+ m_resource->setFrame([this](CWlSurface* r, uint32_t id) { m_callbacks.emplace_back(makeUnique<CWLCallbackResource>(makeUnique<CWlCallback>(m_client, 1, id))); });
m_resource->setOffset([this](CWlSurface* r, int32_t x, int32_t y) {
m_pending.updated.bits.offset = true;
@@ -319,14 +340,14 @@ void CWLSurfaceResource::sendPreferredScale(int32_t scale) {
}
void CWLSurfaceResource::frame(const Time::steady_tp& now) {
- if (m_current.callbacks.empty())
+ if (m_callbacks.empty())
return;
- for (auto const& c : m_current.callbacks) {
+ for (auto const& c : m_callbacks) {
c->send(now);
}
- m_current.callbacks.clear();
+ m_callbacks.clear();
}
void CWLSurfaceResource::resetRole() {
@@ -480,47 +501,6 @@ CBox CWLSurfaceResource::extends() {
return full.getExtents();
}
-void CWLSurfaceResource::scheduleState(WP<SSurfaceState> state) {
- auto whenReadable = [this, surf = m_self, state] {
- if (!surf || state.expired() || m_pendingStates.empty())
- return;
-
- while (!m_pendingStates.empty() && m_pendingStates.front() != state) {
- commitState(*m_pendingStates.front());
- m_pendingStates.pop();
- }
-
- commitState(*m_pendingStates.front());
- m_pendingStates.pop();
-
- // If more states are queued, schedule next state
- if (!m_pendingStates.empty()) {
- scheduleState(m_pendingStates.front());
- } else {
- m_pendingWaiting = false;
- }
- };
-
- if (state->updated.bits.acquire) {
- // wait on acquire point for this surface, from explicit sync protocol
- state->acquire.addWaiter(std::move(whenReadable));
- } else if (state->buffer && state->buffer->isSynchronous()) {
- // synchronous (shm) buffers can be read immediately
- whenReadable();
- } else if (state->buffer && state->buffer->type() == Aquamarine::BUFFER_TYPE_DMABUF && state->buffer->dmabuf().success) {
- // async buffer and is dmabuf, then we can wait on implicit fences
- auto syncFd = dc<CDMABuffer*>(state->buffer.m_buffer.get())->exportSyncFile();
-
- if (syncFd.isValid())
- g_pEventLoopManager->doOnReadable(std::move(syncFd), std::move(whenReadable));
- else
- whenReadable();
- } else {
- // state commit without a buffer.
- whenReadable();
- }
-}
-
void CWLSurfaceResource::commitState(SSurfaceState& state) {
auto lastTexture = m_current.texture;
m_current.updateFrom(state);
diff --git a/src/protocols/core/Compositor.hpp b/src/protocols/core/Compositor.hpp
index dc61917d..0eff3f08 100644
--- a/src/protocols/core/Compositor.hpp
+++ b/src/protocols/core/Compositor.hpp
@@ -35,21 +35,13 @@ class CContentType;
class CWLCallbackResource {
public:
- CWLCallbackResource(SP<CWlCallback>&& resource_);
- ~CWLCallbackResource() noexcept = default;
- // disable copy
- CWLCallbackResource(const CWLCallbackResource&) = delete;
- CWLCallbackResource& operator=(const CWLCallbackResource&) = delete;
+ CWLCallbackResource(UP<CWlCallback>&& resource_);
- // allow move
- CWLCallbackResource(CWLCallbackResource&&) noexcept = default;
- CWLCallbackResource& operator=(CWLCallbackResource&&) noexcept = default;
-
- bool good();
- void send(const Time::steady_tp& now);
+ bool good();
+ void send(const Time::steady_tp& now);
private:
- SP<CWlCallback> m_resource;
+ UP<CWlCallback> m_resource;
};
class CWLRegionResource {
@@ -102,8 +94,8 @@ class CWLSurfaceResource {
SSurfaceState m_current;
SSurfaceState m_pending;
std::queue<UP<SSurfaceState>> m_pendingStates;
- bool m_pendingWaiting = false;
+ std::vector<UP<CWLCallbackResource>> m_callbacks;
WP<CWLSurfaceResource> m_self;
WP<CWLSurface> m_hlSurface;
std::vector<PHLMONITORREF> m_enteredOutputs;
@@ -118,7 +110,6 @@ class CWLSurfaceResource {
SP<CWLSurfaceResource> findFirstPreorder(std::function<bool(SP<CWLSurfaceResource>)> fn);
SP<CWLSurfaceResource> findWithCM();
void presentFeedback(const Time::steady_tp& when, PHLMONITOR pMonitor, bool discarded = false);
- void scheduleState(WP<SSurfaceState> state);
void commitState(SSurfaceState& state);
NColorManagement::SImageDescription getPreferredImageDescription();
void sortSubsurfaces();
diff --git a/src/protocols/types/SurfaceState.cpp b/src/protocols/types/SurfaceState.cpp
index 50e59049..a8838170 100644
--- a/src/protocols/types/SurfaceState.cpp
+++ b/src/protocols/types/SurfaceState.cpp
@@ -75,10 +75,6 @@ void SSurfaceState::updateFrom(SSurfaceState& ref) {
if (ref.updated.bits.damage) {
damage = ref.damage;
bufferDamage = ref.bufferDamage;
- } else {
- // damage is always relative to the current commit
- damage.clear();
- bufferDamage.clear();
}
if (ref.updated.bits.input)
@@ -104,9 +100,4 @@ void SSurfaceState::updateFrom(SSurfaceState& ref) {
if (ref.updated.bits.acked)
ackedSize = ref.ackedSize;
-
- if (ref.updated.bits.frame) {
- callbacks.insert(callbacks.end(), std::make_move_iterator(ref.callbacks.begin()), std::make_move_iterator(ref.callbacks.end()));
- ref.callbacks.clear();
- }
}
diff --git a/src/protocols/types/SurfaceState.hpp b/src/protocols/types/SurfaceState.hpp
index e6764eda..eb50a988 100644
--- a/src/protocols/types/SurfaceState.hpp
+++ b/src/protocols/types/SurfaceState.hpp
@@ -6,7 +6,6 @@
class CTexture;
class CDRMSyncPointState;
-class CWLCallbackResource;
struct SSurfaceState {
union {
@@ -22,7 +21,6 @@ struct SSurfaceState {
bool viewport : 1;
bool acquire : 1;
bool acked : 1;
- bool frame : 1;
} bits;
} updated;
@@ -43,9 +41,6 @@ struct SSurfaceState {
// for xdg_shell resizing
Vector2D ackedSize;
- // for wl_surface::frame callbacks.
- std::vector<SP<CWLCallbackResource>> callbacks;
-
// viewporter protocol surface state
struct {
bool hasDestination = false;