mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-15 20:13:49 -07:00
syncobj: refactor point timelines (#9689)
no need to store the resource, just store the csynctimeline as a shared pointer and make the timeline own the syncobj fd.
This commit is contained in:
@@ -19,12 +19,13 @@ SP<CSyncTimeline> CSyncTimeline::create(int drmFD_) {
|
|||||||
return timeline;
|
return timeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
SP<CSyncTimeline> CSyncTimeline::create(int drmFD_, int drmSyncobjFD) {
|
SP<CSyncTimeline> CSyncTimeline::create(int drmFD_, CFileDescriptor&& drmSyncobjFD) {
|
||||||
auto timeline = SP<CSyncTimeline>(new CSyncTimeline);
|
auto timeline = SP<CSyncTimeline>(new CSyncTimeline);
|
||||||
timeline->drmFD = drmFD_;
|
timeline->drmFD = drmFD_;
|
||||||
timeline->self = timeline;
|
timeline->syncobjFd = std::move(drmSyncobjFD);
|
||||||
|
timeline->self = timeline;
|
||||||
|
|
||||||
if (drmSyncobjFDToHandle(drmFD_, drmSyncobjFD, &timeline->handle)) {
|
if (drmSyncobjFDToHandle(drmFD_, timeline->syncobjFd.get(), &timeline->handle)) {
|
||||||
Debug::log(ERR, "CSyncTimeline: failed to create a drm syncobj from fd??");
|
Debug::log(ERR, "CSyncTimeline: failed to create a drm syncobj from fd??");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,7 @@ struct wl_event_source;
|
|||||||
class CSyncTimeline {
|
class CSyncTimeline {
|
||||||
public:
|
public:
|
||||||
static SP<CSyncTimeline> create(int drmFD_);
|
static SP<CSyncTimeline> create(int drmFD_);
|
||||||
static SP<CSyncTimeline> create(int drmFD_, int drmSyncobjFD);
|
static SP<CSyncTimeline> create(int drmFD_, Hyprutils::OS::CFileDescriptor&& drmSyncobjFD);
|
||||||
~CSyncTimeline();
|
~CSyncTimeline();
|
||||||
|
|
||||||
struct SWaiter {
|
struct SWaiter {
|
||||||
@@ -40,7 +40,8 @@ class CSyncTimeline {
|
|||||||
bool transfer(SP<CSyncTimeline> from, uint64_t fromPoint, uint64_t toPoint);
|
bool transfer(SP<CSyncTimeline> from, uint64_t fromPoint, uint64_t toPoint);
|
||||||
void signal(uint64_t point);
|
void signal(uint64_t point);
|
||||||
|
|
||||||
int drmFD = -1;
|
int drmFD = -1;
|
||||||
|
Hyprutils::OS::CFileDescriptor syncobjFd;
|
||||||
uint32_t handle = 0;
|
uint32_t handle = 0;
|
||||||
WP<CSyncTimeline> self;
|
WP<CSyncTimeline> self;
|
||||||
|
|
||||||
|
@@ -9,50 +9,27 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
using namespace Hyprutils::OS;
|
using namespace Hyprutils::OS;
|
||||||
|
|
||||||
CDRMSyncPointState::CDRMSyncPointState(WP<CDRMSyncobjTimelineResource> resource_, uint64_t point_) : m_resource(resource_), m_point(point_) {}
|
CDRMSyncPointState::CDRMSyncPointState(SP<CSyncTimeline> timeline_, uint64_t point_) : m_timeline(timeline_), m_point(point_) {}
|
||||||
|
|
||||||
const uint64_t& CDRMSyncPointState::point() {
|
const uint64_t& CDRMSyncPointState::point() {
|
||||||
return m_point;
|
return m_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
WP<CDRMSyncobjTimelineResource> CDRMSyncPointState::resource() {
|
|
||||||
return m_resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
WP<CSyncTimeline> CDRMSyncPointState::timeline() {
|
WP<CSyncTimeline> CDRMSyncPointState::timeline() {
|
||||||
if (expired()) {
|
return m_timeline;
|
||||||
Debug::log(ERR, "CDRMSyncPointState: getting a timeline on a expired point");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_resource->timeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CDRMSyncPointState::expired() {
|
|
||||||
return m_resource.expired() || !m_resource->timeline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UP<CSyncReleaser> CDRMSyncPointState::createSyncRelease() {
|
UP<CSyncReleaser> CDRMSyncPointState::createSyncRelease() {
|
||||||
if (expired()) {
|
|
||||||
Debug::log(ERR, "CDRMSyncPointState: creating a sync releaser on an expired point");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_releaseTaken)
|
if (m_releaseTaken)
|
||||||
Debug::log(ERR, "CDRMSyncPointState: creating a sync releaser on an already created SyncRelease");
|
Debug::log(ERR, "CDRMSyncPointState: creating a sync releaser on an already created SyncRelease");
|
||||||
|
|
||||||
m_releaseTaken = true;
|
m_releaseTaken = true;
|
||||||
return makeUnique<CSyncReleaser>(m_resource->timeline, m_point);
|
return makeUnique<CSyncReleaser>(m_timeline, m_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDRMSyncPointState::addWaiter(const std::function<void()>& waiter) {
|
bool CDRMSyncPointState::addWaiter(const std::function<void()>& waiter) {
|
||||||
if (expired()) {
|
|
||||||
Debug::log(ERR, "CDRMSyncPointState: adding a waiter on an expired point");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_acquireCommitted = true;
|
m_acquireCommitted = true;
|
||||||
return m_resource->timeline->addWaiter(waiter, m_point, 0u);
|
return m_timeline->addWaiter(waiter, m_point, 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDRMSyncPointState::comitted() {
|
bool CDRMSyncPointState::comitted() {
|
||||||
@@ -60,21 +37,11 @@ bool CDRMSyncPointState::comitted() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CFileDescriptor CDRMSyncPointState::exportAsFD() {
|
CFileDescriptor CDRMSyncPointState::exportAsFD() {
|
||||||
if (expired()) {
|
return m_timeline->exportAsSyncFileFD(m_point);
|
||||||
Debug::log(ERR, "CDRMSyncPointState: exporting a FD on an expired point");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_resource->timeline->exportAsSyncFileFD(m_point);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDRMSyncPointState::signal() {
|
void CDRMSyncPointState::signal() {
|
||||||
if (expired()) {
|
m_timeline->signal(m_point);
|
||||||
Debug::log(ERR, "CDRMSyncPointState: signaling on an expired point");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_resource->timeline->signal(m_point);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(UP<CWpLinuxDrmSyncobjSurfaceV1>&& resource_, SP<CWLSurfaceResource> surface_) :
|
CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(UP<CWpLinuxDrmSyncobjSurfaceV1>&& resource_, SP<CWLSurfaceResource> surface_) :
|
||||||
@@ -94,7 +61,7 @@ CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(UP<CWpLinuxDrmSyncobjSurf
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto timeline = CDRMSyncobjTimelineResource::fromResource(timeline_);
|
auto timeline = CDRMSyncobjTimelineResource::fromResource(timeline_);
|
||||||
pendingAcquire = {timeline, ((uint64_t)hi << 32) | (uint64_t)lo};
|
pendingAcquire = {timeline->timeline, ((uint64_t)hi << 32) | (uint64_t)lo};
|
||||||
});
|
});
|
||||||
|
|
||||||
resource->setSetReleasePoint([this](CWpLinuxDrmSyncobjSurfaceV1* r, wl_resource* timeline_, uint32_t hi, uint32_t lo) {
|
resource->setSetReleasePoint([this](CWpLinuxDrmSyncobjSurfaceV1* r, wl_resource* timeline_, uint32_t hi, uint32_t lo) {
|
||||||
@@ -104,7 +71,7 @@ CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(UP<CWpLinuxDrmSyncobjSurf
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto timeline = CDRMSyncobjTimelineResource::fromResource(timeline_);
|
auto timeline = CDRMSyncobjTimelineResource::fromResource(timeline_);
|
||||||
pendingRelease = {timeline, ((uint64_t)hi << 32) | (uint64_t)lo};
|
pendingRelease = {timeline->timeline, ((uint64_t)hi << 32) | (uint64_t)lo};
|
||||||
});
|
});
|
||||||
|
|
||||||
listeners.surfacePrecommit = surface->events.precommit.registerListener([this](std::any d) {
|
listeners.surfacePrecommit = surface->events.precommit.registerListener([this](std::any d) {
|
||||||
@@ -126,12 +93,12 @@ CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(UP<CWpLinuxDrmSyncobjSurf
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pendingAcquire.expired()) {
|
if (pendingAcquire.timeline()) {
|
||||||
surface->pending.buffer->acquire = makeUnique<CDRMSyncPointState>(std::move(pendingAcquire));
|
surface->pending.buffer->acquire = makeUnique<CDRMSyncPointState>(std::move(pendingAcquire));
|
||||||
pendingAcquire = {};
|
pendingAcquire = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pendingRelease.expired()) {
|
if (pendingRelease.timeline()) {
|
||||||
surface->pending.buffer->release = makeUnique<CDRMSyncPointState>(std::move(pendingRelease));
|
surface->pending.buffer->release = makeUnique<CDRMSyncPointState>(std::move(pendingRelease));
|
||||||
pendingRelease = {};
|
pendingRelease = {};
|
||||||
}
|
}
|
||||||
@@ -158,8 +125,8 @@ CDRMSyncobjSurfaceResource::CDRMSyncobjSurfaceResource(UP<CWpLinuxDrmSyncobjSurf
|
|||||||
|
|
||||||
void CDRMSyncobjSurfaceResource::removeAllWaiters() {
|
void CDRMSyncobjSurfaceResource::removeAllWaiters() {
|
||||||
for (auto& s : pendingStates) {
|
for (auto& s : pendingStates) {
|
||||||
if (s && s->buffer && s->buffer->acquire && !s->buffer->acquire->expired())
|
if (s && s->buffer && s->buffer->acquire)
|
||||||
s->buffer->acquire->resource()->timeline->removeAllWaiters();
|
s->buffer->acquire->timeline()->removeAllWaiters();
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingStates.clear();
|
pendingStates.clear();
|
||||||
@@ -212,7 +179,7 @@ CDRMSyncobjTimelineResource::CDRMSyncobjTimelineResource(UP<CWpLinuxDrmSyncobjTi
|
|||||||
resource->setOnDestroy([this](CWpLinuxDrmSyncobjTimelineV1* r) { PROTO::sync->destroyResource(this); });
|
resource->setOnDestroy([this](CWpLinuxDrmSyncobjTimelineV1* r) { PROTO::sync->destroyResource(this); });
|
||||||
resource->setDestroy([this](CWpLinuxDrmSyncobjTimelineV1* r) { PROTO::sync->destroyResource(this); });
|
resource->setDestroy([this](CWpLinuxDrmSyncobjTimelineV1* r) { PROTO::sync->destroyResource(this); });
|
||||||
|
|
||||||
timeline = CSyncTimeline::create(PROTO::sync->drmFD, fd.get());
|
timeline = CSyncTimeline::create(PROTO::sync->drmFD, std::move(fd));
|
||||||
|
|
||||||
if (!timeline) {
|
if (!timeline) {
|
||||||
resource->error(WP_LINUX_DRM_SYNCOBJ_MANAGER_V1_ERROR_INVALID_TIMELINE, "Timeline failed importing");
|
resource->error(WP_LINUX_DRM_SYNCOBJ_MANAGER_V1_ERROR_INVALID_TIMELINE, "Timeline failed importing");
|
||||||
|
@@ -17,13 +17,11 @@ struct SSurfaceState;
|
|||||||
class CDRMSyncPointState {
|
class CDRMSyncPointState {
|
||||||
public:
|
public:
|
||||||
CDRMSyncPointState() = default;
|
CDRMSyncPointState() = default;
|
||||||
CDRMSyncPointState(WP<CDRMSyncobjTimelineResource> resource_, uint64_t point_);
|
CDRMSyncPointState(SP<CSyncTimeline> timeline_, uint64_t point_);
|
||||||
~CDRMSyncPointState() = default;
|
~CDRMSyncPointState() = default;
|
||||||
|
|
||||||
const uint64_t& point();
|
const uint64_t& point();
|
||||||
WP<CDRMSyncobjTimelineResource> resource();
|
|
||||||
WP<CSyncTimeline> timeline();
|
WP<CSyncTimeline> timeline();
|
||||||
bool expired();
|
|
||||||
Hyprutils::Memory::CUniquePointer<CSyncReleaser> createSyncRelease();
|
Hyprutils::Memory::CUniquePointer<CSyncReleaser> createSyncRelease();
|
||||||
bool addWaiter(const std::function<void()>& waiter);
|
bool addWaiter(const std::function<void()>& waiter);
|
||||||
bool comitted();
|
bool comitted();
|
||||||
@@ -31,11 +29,10 @@ class CDRMSyncPointState {
|
|||||||
void signal();
|
void signal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WP<CDRMSyncobjTimelineResource> m_resource = {};
|
SP<CSyncTimeline> m_timeline = {};
|
||||||
uint64_t m_point = 0;
|
uint64_t m_point = 0;
|
||||||
WP<CSyncTimeline> m_timeline = {};
|
bool m_acquireCommitted = false;
|
||||||
bool m_acquireCommitted = false;
|
bool m_releaseTaken = false;
|
||||||
bool m_releaseTaken = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDRMSyncobjSurfaceResource {
|
class CDRMSyncobjSurfaceResource {
|
||||||
|
Reference in New Issue
Block a user