core/compositor: revert make wl_surface::frame follow pending states (#11896)
This reverts commit 17e77e0407.
Reverted due to severe performance degradation due to accumulating frame
callbacks
This commit is contained in:
parent
02cda6bebf
commit
dc72259a54
5 changed files with 49 additions and 95 deletions
|
|
@ -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() {
|
bool CWLCallbackResource::good() {
|
||||||
return m_resource && m_resource->resource();
|
return m_resource->resource();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWLCallbackResource::send(const Time::steady_tp& now) {
|
void CWLCallbackResource::send(const Time::steady_tp& now) {
|
||||||
if (!good())
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_resource->sendDone(Time::millis(now));
|
m_resource->sendDone(Time::millis(now));
|
||||||
m_resource.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CWLRegionResource::CWLRegionResource(SP<CWlRegion> resource_) : m_resource(resource_) {
|
CWLRegionResource::CWLRegionResource(SP<CWlRegion> resource_) : m_resource(resource_) {
|
||||||
|
|
@ -131,16 +127,17 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : m_resource(re
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// null buffer attached
|
if ((!m_pending.updated.bits.buffer) || // no new buffer attached
|
||||||
if (!m_pending.buffer && !m_pending.texture && m_pending.updated.bits.buffer) {
|
(!m_pending.buffer && !m_pending.texture) // null buffer attached
|
||||||
|
) {
|
||||||
commitState(m_pending);
|
commitState(m_pending);
|
||||||
|
|
||||||
// remove any pending states.
|
if (!m_pending.buffer && !m_pending.texture) {
|
||||||
while (!m_pendingStates.empty()) {
|
// null buffer attached, remove any pending states.
|
||||||
m_pendingStates.pop();
|
while (!m_pendingStates.empty()) {
|
||||||
|
m_pendingStates.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pendingWaiting = false;
|
|
||||||
m_pending.reset();
|
m_pending.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -149,9 +146,36 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : m_resource(re
|
||||||
const auto& state = m_pendingStates.emplace(makeUnique<SSurfaceState>(m_pending));
|
const auto& state = m_pendingStates.emplace(makeUnique<SSurfaceState>(m_pending));
|
||||||
m_pending.reset();
|
m_pending.reset();
|
||||||
|
|
||||||
if (!m_pendingWaiting) {
|
auto whenReadable = [this, surf = m_self, state = WP<SSurfaceState>(m_pendingStates.back())] {
|
||||||
m_pendingWaiting = true;
|
if (!surf || state.expired())
|
||||||
scheduleState(state);
|
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_pending.opaque = RG->m_region;
|
||||||
});
|
});
|
||||||
|
|
||||||
m_resource->setFrame([this](CWlSurface* r, uint32_t id) {
|
m_resource->setFrame([this](CWlSurface* r, uint32_t id) { m_callbacks.emplace_back(makeUnique<CWLCallbackResource>(makeUnique<CWlCallback>(m_client, 1, id))); });
|
||||||
m_pending.updated.bits.frame = true;
|
|
||||||
m_pending.callbacks.emplace_back(makeShared<CWLCallbackResource>(makeShared<CWlCallback>(m_client, 1, id)));
|
|
||||||
});
|
|
||||||
|
|
||||||
m_resource->setOffset([this](CWlSurface* r, int32_t x, int32_t y) {
|
m_resource->setOffset([this](CWlSurface* r, int32_t x, int32_t y) {
|
||||||
m_pending.updated.bits.offset = true;
|
m_pending.updated.bits.offset = true;
|
||||||
|
|
@ -319,14 +340,14 @@ void CWLSurfaceResource::sendPreferredScale(int32_t scale) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWLSurfaceResource::frame(const Time::steady_tp& now) {
|
void CWLSurfaceResource::frame(const Time::steady_tp& now) {
|
||||||
if (m_current.callbacks.empty())
|
if (m_callbacks.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto const& c : m_current.callbacks) {
|
for (auto const& c : m_callbacks) {
|
||||||
c->send(now);
|
c->send(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_current.callbacks.clear();
|
m_callbacks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWLSurfaceResource::resetRole() {
|
void CWLSurfaceResource::resetRole() {
|
||||||
|
|
@ -480,47 +501,6 @@ CBox CWLSurfaceResource::extends() {
|
||||||
return full.getExtents();
|
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) {
|
void CWLSurfaceResource::commitState(SSurfaceState& state) {
|
||||||
auto lastTexture = m_current.texture;
|
auto lastTexture = m_current.texture;
|
||||||
m_current.updateFrom(state);
|
m_current.updateFrom(state);
|
||||||
|
|
|
||||||
|
|
@ -35,21 +35,13 @@ class CContentType;
|
||||||
|
|
||||||
class CWLCallbackResource {
|
class CWLCallbackResource {
|
||||||
public:
|
public:
|
||||||
CWLCallbackResource(SP<CWlCallback>&& resource_);
|
CWLCallbackResource(UP<CWlCallback>&& resource_);
|
||||||
~CWLCallbackResource() noexcept = default;
|
|
||||||
// disable copy
|
|
||||||
CWLCallbackResource(const CWLCallbackResource&) = delete;
|
|
||||||
CWLCallbackResource& operator=(const CWLCallbackResource&) = delete;
|
|
||||||
|
|
||||||
// allow move
|
bool good();
|
||||||
CWLCallbackResource(CWLCallbackResource&&) noexcept = default;
|
void send(const Time::steady_tp& now);
|
||||||
CWLCallbackResource& operator=(CWLCallbackResource&&) noexcept = default;
|
|
||||||
|
|
||||||
bool good();
|
|
||||||
void send(const Time::steady_tp& now);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SP<CWlCallback> m_resource;
|
UP<CWlCallback> m_resource;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CWLRegionResource {
|
class CWLRegionResource {
|
||||||
|
|
@ -102,8 +94,8 @@ class CWLSurfaceResource {
|
||||||
SSurfaceState m_current;
|
SSurfaceState m_current;
|
||||||
SSurfaceState m_pending;
|
SSurfaceState m_pending;
|
||||||
std::queue<UP<SSurfaceState>> m_pendingStates;
|
std::queue<UP<SSurfaceState>> m_pendingStates;
|
||||||
bool m_pendingWaiting = false;
|
|
||||||
|
|
||||||
|
std::vector<UP<CWLCallbackResource>> m_callbacks;
|
||||||
WP<CWLSurfaceResource> m_self;
|
WP<CWLSurfaceResource> m_self;
|
||||||
WP<CWLSurface> m_hlSurface;
|
WP<CWLSurface> m_hlSurface;
|
||||||
std::vector<PHLMONITORREF> m_enteredOutputs;
|
std::vector<PHLMONITORREF> m_enteredOutputs;
|
||||||
|
|
@ -118,7 +110,6 @@ class CWLSurfaceResource {
|
||||||
SP<CWLSurfaceResource> findFirstPreorder(std::function<bool(SP<CWLSurfaceResource>)> fn);
|
SP<CWLSurfaceResource> findFirstPreorder(std::function<bool(SP<CWLSurfaceResource>)> fn);
|
||||||
SP<CWLSurfaceResource> findWithCM();
|
SP<CWLSurfaceResource> findWithCM();
|
||||||
void presentFeedback(const Time::steady_tp& when, PHLMONITOR pMonitor, bool discarded = false);
|
void presentFeedback(const Time::steady_tp& when, PHLMONITOR pMonitor, bool discarded = false);
|
||||||
void scheduleState(WP<SSurfaceState> state);
|
|
||||||
void commitState(SSurfaceState& state);
|
void commitState(SSurfaceState& state);
|
||||||
NColorManagement::SImageDescription getPreferredImageDescription();
|
NColorManagement::SImageDescription getPreferredImageDescription();
|
||||||
void sortSubsurfaces();
|
void sortSubsurfaces();
|
||||||
|
|
|
||||||
|
|
@ -75,10 +75,6 @@ void SSurfaceState::updateFrom(SSurfaceState& ref) {
|
||||||
if (ref.updated.bits.damage) {
|
if (ref.updated.bits.damage) {
|
||||||
damage = ref.damage;
|
damage = ref.damage;
|
||||||
bufferDamage = ref.bufferDamage;
|
bufferDamage = ref.bufferDamage;
|
||||||
} else {
|
|
||||||
// damage is always relative to the current commit
|
|
||||||
damage.clear();
|
|
||||||
bufferDamage.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ref.updated.bits.input)
|
if (ref.updated.bits.input)
|
||||||
|
|
@ -104,9 +100,4 @@ void SSurfaceState::updateFrom(SSurfaceState& ref) {
|
||||||
|
|
||||||
if (ref.updated.bits.acked)
|
if (ref.updated.bits.acked)
|
||||||
ackedSize = ref.ackedSize;
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
class CTexture;
|
class CTexture;
|
||||||
class CDRMSyncPointState;
|
class CDRMSyncPointState;
|
||||||
class CWLCallbackResource;
|
|
||||||
|
|
||||||
struct SSurfaceState {
|
struct SSurfaceState {
|
||||||
union {
|
union {
|
||||||
|
|
@ -22,7 +21,6 @@ struct SSurfaceState {
|
||||||
bool viewport : 1;
|
bool viewport : 1;
|
||||||
bool acquire : 1;
|
bool acquire : 1;
|
||||||
bool acked : 1;
|
bool acked : 1;
|
||||||
bool frame : 1;
|
|
||||||
} bits;
|
} bits;
|
||||||
} updated;
|
} updated;
|
||||||
|
|
||||||
|
|
@ -43,9 +41,6 @@ struct SSurfaceState {
|
||||||
// for xdg_shell resizing
|
// for xdg_shell resizing
|
||||||
Vector2D ackedSize;
|
Vector2D ackedSize;
|
||||||
|
|
||||||
// for wl_surface::frame callbacks.
|
|
||||||
std::vector<SP<CWLCallbackResource>> callbacks;
|
|
||||||
|
|
||||||
// viewporter protocol surface state
|
// viewporter protocol surface state
|
||||||
struct {
|
struct {
|
||||||
bool hasDestination = false;
|
bool hasDestination = false;
|
||||||
|
|
|
||||||
|
|
@ -111,9 +111,6 @@ void CTexture::createFromDma(const Aquamarine::SDMABUFAttrs& attrs, void* image)
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTexture::update(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const CRegion& damage) {
|
void CTexture::update(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const CRegion& damage) {
|
||||||
if (damage.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_pHyprRenderer->makeEGLCurrent();
|
g_pHyprRenderer->makeEGLCurrent();
|
||||||
|
|
||||||
const auto format = NFormatUtils::getPixelFormatFromDRM(drmFormat);
|
const auto format = NFormatUtils::getPixelFormatFromDRM(drmFormat);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue