From e156ace712a9dbe04b9a8759072c92f291507881 Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Sat, 22 Feb 2025 19:52:49 +0100 Subject: [PATCH 2/3] syncobj: lets optimize it further lets use unique_pointers all over, add defaulted destructors and make fromResource directly check existing timelines instead of C style casting and return a WP from that. instead of moving the releasepoint vector lets swap it. --- src/protocols/DRMSyncobj.cpp | 31 ++++++++++++++++++------------- src/protocols/DRMSyncobj.hpp | 22 +++++++++++----------- src/protocols/core/Compositor.cpp | 2 +- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/protocols/DRMSyncobj.cpp b/src/protocols/DRMSyncobj.cpp index 63f0946b58c..af2fadfaa7d 100644 --- a/src/protocols/DRMSyncobj.cpp +++ b/src/protocols/DRMSyncobj.cpp @@ -8,7 +8,8 @@ #include using namespace Hyprutils::OS; -CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { +CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(UP&& resource_, SP surface_) : + surface(surface_), resource(std::move(resource_)) { if UNLIKELY (!good()) return; @@ -107,7 +108,7 @@ bool CDRMSyncobjSurfaceResource::good() { return resource->resource(); } -CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP resource_, CFileDescriptor&& fd_) : fd(std::move(fd_)), resource(resource_) { +CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(UP&& resource_, CFileDescriptor&& fd_) : fd(std::move(fd_)), resource(std::move(resource_)) { if UNLIKELY (!good()) return; @@ -124,16 +125,20 @@ CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(SP CDRMSyncobjTimelineResource::fromResource(wl_resource* res) { - auto data = (CDRMSyncobjTimelineResource*)(((CWpLinuxDrmSyncobjTimelineV1*)wl_resource_get_user_data(res))->data()); - return data ? data->self.lock() : nullptr; +WP CDRMSyncobjTimelineResource::fromResource(wl_resource* res) { + for (const auto& t : PROTO::sync->m_vTimelines) { + if (t && t->resource && t->resource->resource() == res) + return t; + } + + return {}; } bool CDRMSyncobjTimelineResource::good() { return resource->resource(); } -CDRMSyncobjManagerResource::CDRMSyncobjManagerResource(SP resource_) : resource(resource_) { +CDRMSyncobjManagerResource::CDRMSyncobjManagerResource(UP&& resource_) : resource(std::move(resource_)) { if UNLIKELY (!good()) return; @@ -157,28 +162,28 @@ CDRMSyncobjManagerResource::CDRMSyncobjManagerResource(SP(makeShared(resource->client(), resource->version(), id), SURF); + const auto& RESOURCE = PROTO::sync->m_vSurfaces.emplace_back( + makeUnique(makeUnique(resource->client(), resource->version(), id), SURF)); if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); + PROTO::sync->m_vSurfaces.pop_back(); return; } - PROTO::sync->m_vSurfaces.emplace_back(RESOURCE); SURF->syncobj = RESOURCE; LOGM(LOG, "New linux_syncobj at {:x} for surface {:x}", (uintptr_t)RESOURCE.get(), (uintptr_t)SURF.get()); }); resource->setImportTimeline([this](CWpLinuxDrmSyncobjManagerV1* r, uint32_t id, int32_t fd) { - auto RESOURCE = makeShared(makeShared(resource->client(), resource->version(), id), CFileDescriptor{fd}); + const auto& RESOURCE = PROTO::sync->m_vTimelines.emplace_back( + makeUnique(makeUnique(resource->client(), resource->version(), id), CFileDescriptor{fd})); if UNLIKELY (!RESOURCE->good()) { resource->noMemory(); + PROTO::sync->m_vTimelines.pop_back(); return; } - PROTO::sync->m_vTimelines.emplace_back(RESOURCE); - RESOURCE->self = RESOURCE; - LOGM(LOG, "New linux_drm_timeline at {:x}", (uintptr_t)RESOURCE.get()); }); } @@ -192,7 +197,7 @@ CDRMSyncobjProtocol::CDRMSyncobjProtocol(const wl_interface* iface, const int& v } void CDRMSyncobjProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); + const auto& RESOURCE = m_vManagers.emplace_back(makeUnique(makeUnique(client, ver, id))); if UNLIKELY (!RESOURCE->good()) { wl_client_post_no_memory(client); diff --git a/src/protocols/DRMSyncobj.hpp b/src/protocols/DRMSyncobj.hpp index 06a3def2565..af4ee3567bd 100644 --- a/src/protocols/DRMSyncobj.hpp +++ b/src/protocols/DRMSyncobj.hpp @@ -13,7 +13,7 @@ class CSyncTimeline; class CDRMSyncobjSurfaceResource { public: - CDRMSyncobjSurfaceResource(SP resource_, SP surface_); + CDRMSyncobjSurfaceResource(UP&& resource_, SP surface_); ~CDRMSyncobjSurfaceResource(); bool good(); @@ -34,7 +34,7 @@ class CDRMSyncobjSurfaceResource { std::vector> releasePoints; private: - SP resource; + UP resource; bool acquireWaiting = false; struct { @@ -45,33 +45,33 @@ class CDRMSyncobjSurfaceResource { class CDRMSyncobjTimelineResource { public: - CDRMSyncobjTimelineResource(SP resource_, Hyprutils::OS::CFileDescriptor&& fd_); + CDRMSyncobjTimelineResource(UP&& resource_, Hyprutils::OS::CFileDescriptor&& fd_); ~CDRMSyncobjTimelineResource() = default; - static SP fromResource(wl_resource*); + static WP fromResource(wl_resource*); bool good(); - WP self; Hyprutils::OS::CFileDescriptor fd; SP timeline; private: - SP resource; + UP resource; }; class CDRMSyncobjManagerResource { public: - CDRMSyncobjManagerResource(SP resource_); + CDRMSyncobjManagerResource(UP&& resource_); bool good(); private: - SP resource; + UP resource; }; class CDRMSyncobjProtocol : public IWaylandProtocol { public: CDRMSyncobjProtocol(const wl_interface* iface, const int& ver, const std::string& name); + ~CDRMSyncobjProtocol() = default; virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); @@ -81,9 +81,9 @@ class CDRMSyncobjProtocol : public IWaylandProtocol { void destroyResource(CDRMSyncobjSurfaceResource* resource); // - std::vector> m_vManagers; - std::vector> m_vTimelines; - std::vector> m_vSurfaces; + std::vector> m_vManagers; + std::vector> m_vTimelines; + std::vector> m_vSurfaces; // int drmFD = -1; diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 87adaeae1be..0dddf8b42c1 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -434,7 +434,7 @@ void CWLSurfaceResource::commitPendingState() { events.roleCommit.emit(); if (syncobj && syncobj->release.resource && syncobj->release.resource->timeline && current.buffer && current.buffer->buffer) - current.buffer->releaser = std::move(syncobj->releasePoints); + current.buffer->releaser.swap(syncobj->releasePoints); if (current.texture) current.texture->m_eTransform = wlTransformToHyprutils(current.transform);