Skip to content

Commit 4d16b72

Browse files
drm-lease: Add Multi-GPU Support
1 parent 225e13c commit 4d16b72

File tree

4 files changed

+58
-45
lines changed

4 files changed

+58
-45
lines changed

src/helpers/Monitor.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,11 @@ void CMonitor::onConnect(bool noRule) {
167167

168168
if (output->nonDesktop) {
169169
Debug::log(LOG, "Not configuring non-desktop output");
170-
if (PROTO::lease)
171-
PROTO::lease->offer(self.lock());
170+
171+
for (auto &lease : PROTO::lease) {
172+
if (lease && output->getBackend() == lease->getBackend())
173+
lease->offer(self.lock());
174+
}
172175

173176
return;
174177
}

src/managers/ProtocolManager.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,9 @@ CProtocolManager::CProtocolManager() {
197197
if (b->type() != Aquamarine::AQ_BACKEND_DRM)
198198
continue;
199199

200-
PROTO::lease = makeUnique<CDRMLeaseProtocol>(&wp_drm_lease_device_v1_interface, 1, "DRMLease");
201-
if (*PENABLEEXPLICIT)
200+
PROTO::lease.push_back(makeUnique<CDRMLeaseProtocol>(&wp_drm_lease_device_v1_interface, 1, "DRMLease", b));
201+
if (*PENABLEEXPLICIT && !PROTO::sync)
202202
PROTO::sync = makeUnique<CDRMSyncobjProtocol>(&wp_linux_drm_syncobj_manager_v1_interface, 1, "DRMSyncobj");
203-
break;
204203
}
205204

206205
if (g_pHyprOpenGL->getDRMFormats().size() > 0) {
@@ -272,7 +271,9 @@ CProtocolManager::~CProtocolManager() {
272271
PROTO::xxColorManagement.reset();
273272
PROTO::frogColorManagement.reset();
274273

275-
PROTO::lease.reset();
274+
for (auto &lease: PROTO::lease) {
275+
lease.reset();
276+
}
276277
PROTO::sync.reset();
277278
PROTO::mesaDRM.reset();
278279
PROTO::linuxDma.reset();

src/protocols/DRMLease.cpp

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ CDRMLeaseResource::CDRMLeaseResource(SP<CWpDrmLeaseV1> resource_, SP<CDRMLeaseRe
1010
if UNLIKELY (!good())
1111
return;
1212

13-
resource->setOnDestroy([this](CWpDrmLeaseV1* r) { PROTO::lease->destroyResource(this); });
14-
resource->setDestroy([this](CWpDrmLeaseV1* r) { PROTO::lease->destroyResource(this); });
15-
1613
parent = request->parent;
1714
requested = request->requested;
1815

16+
resource->setOnDestroy([this](CWpDrmLeaseV1* r) { if (parent.valid()) parent->proto->destroyResource(this); });
17+
resource->setDestroy([this](CWpDrmLeaseV1* r) { if (parent.valid()) parent->proto->destroyResource(this); });
18+
1919
for (auto const& m : requested) {
2020
if (!m->monitor || m->monitor->isBeingLeased) {
2121
LOGM(ERR, "Rejecting lease: no monitor or monitor is being leased for {}", (m->monitor ? m->monitor->szName : "null"));
@@ -82,11 +82,11 @@ CDRMLeaseResource::~CDRMLeaseResource() {
8282
listeners.destroyLease.reset();
8383
}
8484

85-
CDRMLeaseRequestResource::CDRMLeaseRequestResource(SP<CWpDrmLeaseRequestV1> resource_) : resource(resource_) {
85+
CDRMLeaseRequestResource::CDRMLeaseRequestResource(WP<CDRMLeaseDeviceResource> parent_, SP<CWpDrmLeaseRequestV1> resource_) : parent(parent_), resource(resource_) {
8686
if UNLIKELY (!good())
8787
return;
8888

89-
resource->setOnDestroy([this](CWpDrmLeaseRequestV1* r) { PROTO::lease->destroyResource(this); });
89+
resource->setOnDestroy([this](CWpDrmLeaseRequestV1* r) { parent->proto->destroyResource(this); });
9090

9191
resource->setRequestConnector([this](CWpDrmLeaseRequestV1* r, wl_resource* conn) {
9292
if (!conn) {
@@ -118,10 +118,10 @@ CDRMLeaseRequestResource::CDRMLeaseRequestResource(SP<CWpDrmLeaseRequestV1> reso
118118
return;
119119
}
120120

121-
PROTO::lease->m_vLeases.emplace_back(RESOURCE);
121+
parent->proto->m_vLeases.emplace_back(RESOURCE);
122122

123123
// per protcol, after submit, this is dead.
124-
PROTO::lease->destroyResource(this);
124+
parent->proto->destroyResource(this);
125125
});
126126
}
127127

@@ -134,12 +134,12 @@ SP<CDRMLeaseConnectorResource> CDRMLeaseConnectorResource::fromResource(wl_resou
134134
return data ? data->self.lock() : nullptr;
135135
}
136136

137-
CDRMLeaseConnectorResource::CDRMLeaseConnectorResource(SP<CWpDrmLeaseConnectorV1> resource_, PHLMONITOR monitor_) : monitor(monitor_), resource(resource_) {
137+
CDRMLeaseConnectorResource::CDRMLeaseConnectorResource(WP<CDRMLeaseDeviceResource> parent_, SP<CWpDrmLeaseConnectorV1> resource_, PHLMONITOR monitor_) : parent(parent_), monitor(monitor_), resource(resource_) {
138138
if UNLIKELY (!good())
139139
return;
140140

141-
resource->setOnDestroy([this](CWpDrmLeaseConnectorV1* r) { PROTO::lease->destroyResource(this); });
142-
resource->setDestroy([this](CWpDrmLeaseConnectorV1* r) { PROTO::lease->destroyResource(this); });
141+
resource->setOnDestroy([this](CWpDrmLeaseConnectorV1* r) { if (parent.valid()) parent->proto->destroyResource(this); });
142+
resource->setDestroy([this](CWpDrmLeaseConnectorV1* r) { if (parent.valid()) parent->proto->destroyResource(this); });
143143

144144
resource->setData(this);
145145

@@ -163,30 +163,31 @@ void CDRMLeaseConnectorResource::sendData() {
163163
resource->sendDone();
164164
}
165165

166-
CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP<CWpDrmLeaseDeviceV1> resource_) : resource(resource_) {
166+
CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(WP<CDRMLeaseProtocol> proto_, SP<CWpDrmLeaseDeviceV1> resource_) : proto(proto_), resource(resource_) {
167167
if UNLIKELY (!good())
168168
return;
169169

170-
resource->setOnDestroy([this](CWpDrmLeaseDeviceV1* r) { PROTO::lease->destroyResource(this); });
171-
resource->setRelease([this](CWpDrmLeaseDeviceV1* r) { PROTO::lease->destroyResource(this); });
170+
resource->setOnDestroy([this](CWpDrmLeaseDeviceV1* r) { proto->destroyResource(this); });
171+
resource->setRelease([this](CWpDrmLeaseDeviceV1* r) { proto->destroyResource(this); });
172172

173173
resource->setCreateLeaseRequest([this](CWpDrmLeaseDeviceV1* r, uint32_t id) {
174-
auto RESOURCE = makeShared<CDRMLeaseRequestResource>(makeShared<CWpDrmLeaseRequestV1>(resource->client(), resource->version(), id));
174+
auto RESOURCE = makeShared<CDRMLeaseRequestResource>(self, makeShared<CWpDrmLeaseRequestV1>(resource->client(), resource->version(), id));
175175
if UNLIKELY (!RESOURCE) {
176176
resource->noMemory();
177177
return;
178178
}
179179

180180
RESOURCE->self = RESOURCE;
181181

182-
PROTO::lease->m_vRequests.emplace_back(RESOURCE);
182+
proto->m_vRequests.emplace_back(RESOURCE);
183183

184184
LOGM(LOG, "New lease request {}", id);
185185

186186
RESOURCE->parent = self;
187187
});
188188

189-
CFileDescriptor fd{((Aquamarine::CDRMBackend*)PROTO::lease->primaryDevice->backend.get())->getNonMasterFD()};
189+
auto &primaryDevice = proto->primaryDevice;
190+
CFileDescriptor fd{((Aquamarine::CDRMBackend*)primaryDevice->backend.get())->getNonMasterFD()};
190191
if (!fd.isValid()) {
191192
LOGM(ERR, "Failed to dup fd in lease");
192193
return;
@@ -195,7 +196,7 @@ CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP<CWpDrmLeaseDeviceV1> resourc
195196
LOGM(LOG, "Sending DRMFD {} to new lease device", fd.get());
196197
resource->sendDrmFd(fd.get());
197198

198-
for (auto const& m : PROTO::lease->primaryDevice->offeredOutputs) {
199+
for (auto const& m : primaryDevice->offeredOutputs) {
199200
if (m)
200201
sendConnector(m.lock());
201202
}
@@ -211,7 +212,7 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) {
211212
if (std::find_if(connectorsSent.begin(), connectorsSent.end(), [monitor](const auto& e) { return e && !e->dead && e->monitor == monitor; }) != connectorsSent.end())
212213
return;
213214

214-
auto RESOURCE = makeShared<CDRMLeaseConnectorResource>(makeShared<CWpDrmLeaseConnectorV1>(resource->client(), resource->version(), 0), monitor);
215+
auto RESOURCE = makeShared<CDRMLeaseConnectorResource>(self, makeShared<CWpDrmLeaseConnectorV1>(resource->client(), resource->version(), 0), monitor);
215216
if UNLIKELY (!RESOURCE) {
216217
resource->noMemory();
217218
return;
@@ -223,7 +224,7 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) {
223224
LOGM(LOG, "Sending new connector {}", monitor->szName);
224225

225226
connectorsSent.emplace_back(RESOURCE);
226-
PROTO::lease->m_vConnectors.emplace_back(RESOURCE);
227+
proto->m_vConnectors.emplace_back(RESOURCE);
227228

228229
resource->sendConnector(RESOURCE->resource.get());
229230

@@ -244,25 +245,26 @@ CDRMLeaseDevice::CDRMLeaseDevice(SP<Aquamarine::CDRMBackend> drmBackend) : backe
244245
name = drm->gpuName;
245246
}
246247

247-
CDRMLeaseProtocol::CDRMLeaseProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
248-
for (auto const& b : g_pCompositor->m_pAqBackend->getImplementations()) {
249-
if (b->type() != Aquamarine::AQ_BACKEND_DRM)
250-
continue;
251-
252-
auto drm = ((Aquamarine::CDRMBackend*)b.get())->self.lock();
248+
template<class UnaryPred> static void findCDRMLeaseProtocolAndDo(CDRMLeaseProtocol *self, UnaryPred pred) {
249+
auto ref = std::ranges::find_if(PROTO::lease.begin(), PROTO::lease.end(), [self](auto &e) { return e.get() == self; });
250+
if (ref != PROTO::lease.end()) {
251+
pred(*ref);
252+
}
253+
}
253254

254-
primaryDevice = makeShared<CDRMLeaseDevice>(drm);
255+
CDRMLeaseProtocol::CDRMLeaseProtocol(const wl_interface* iface, const int& ver, const std::string& name, SP<Aquamarine::IBackendImplementation> backend) : IWaylandProtocol(iface, ver, name) {
256+
auto drm = ((Aquamarine::CDRMBackend*)backend.get())->self.lock();
257+
primaryDevice = makeShared<CDRMLeaseDevice>(drm);
255258

256-
if (primaryDevice->success)
257-
break;
259+
if (!primaryDevice || !primaryDevice->success) {
260+
g_pEventLoopManager->doLater([this]() { findCDRMLeaseProtocolAndDo(this, [](auto &lease) {lease.reset();}); });
258261
}
259-
260-
if (!primaryDevice || !primaryDevice->success)
261-
g_pEventLoopManager->doLater([]() { PROTO::lease.reset(); });
262262
}
263263

264264
void CDRMLeaseProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
265-
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CDRMLeaseDeviceResource>(makeShared<CWpDrmLeaseDeviceV1>(client, ver, id)));
265+
findCDRMLeaseProtocolAndDo(this, [this](auto &lease){self = WP<CDRMLeaseProtocol>(lease); });
266+
267+
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CDRMLeaseDeviceResource>(self, makeShared<CWpDrmLeaseDeviceV1>(client, ver, id)));
266268

267269
if UNLIKELY (!RESOURCE->good()) {
268270
wl_client_post_no_memory(client);
@@ -292,14 +294,16 @@ void CDRMLeaseProtocol::destroyResource(CDRMLeaseResource* resource) {
292294
std::erase_if(m_vLeases, [resource](const auto& e) { return e.get() == resource; });
293295
}
294296

297+
SP<Aquamarine::IBackendImplementation> CDRMLeaseProtocol::getBackend() {
298+
return primaryDevice->backend;
299+
}
300+
295301
void CDRMLeaseProtocol::offer(PHLMONITOR monitor) {
296302
std::erase_if(primaryDevice->offeredOutputs, [](const auto& e) { return e.expired(); });
297303
if (std::find(primaryDevice->offeredOutputs.begin(), primaryDevice->offeredOutputs.end(), monitor) != primaryDevice->offeredOutputs.end())
298304
return;
299-
300305
if (monitor->output->getBackend()->type() != Aquamarine::AQ_BACKEND_DRM)
301306
return;
302-
303307
if (monitor->output->getBackend() != primaryDevice->backend) {
304308
LOGM(ERR, "Monitor {} cannot be leased: primaryDevice lease is for a different device", monitor->szName);
305309
return;

src/protocols/DRMLease.hpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <aquamarine/backend/Backend.hpp>
34
#include <vector>
45
#include <unordered_map>
56
#include "WaylandProtocol.hpp"
@@ -42,7 +43,7 @@ class CDRMLeaseResource {
4243

4344
class CDRMLeaseRequestResource {
4445
public:
45-
CDRMLeaseRequestResource(SP<CWpDrmLeaseRequestV1> resource_);
46+
CDRMLeaseRequestResource(WP<CDRMLeaseDeviceResource> parent, SP<CWpDrmLeaseRequestV1> resource_);
4647

4748
bool good();
4849

@@ -56,7 +57,7 @@ class CDRMLeaseRequestResource {
5657

5758
class CDRMLeaseConnectorResource {
5859
public:
59-
CDRMLeaseConnectorResource(SP<CWpDrmLeaseConnectorV1> resource_, PHLMONITOR monitor_);
60+
CDRMLeaseConnectorResource(WP<CDRMLeaseDeviceResource> parent, SP<CWpDrmLeaseConnectorV1> resource_, PHLMONITOR monitor_);
6061
static SP<CDRMLeaseConnectorResource> fromResource(wl_resource*);
6162

6263
bool good();
@@ -79,14 +80,15 @@ class CDRMLeaseConnectorResource {
7980

8081
class CDRMLeaseDeviceResource {
8182
public:
82-
CDRMLeaseDeviceResource(SP<CWpDrmLeaseDeviceV1> resource_);
83+
CDRMLeaseDeviceResource(WP<CDRMLeaseProtocol> proto, SP<CWpDrmLeaseDeviceV1> resource_);
8384

8485
bool good();
8586
void sendConnector(PHLMONITOR monitor);
8687

8788
std::vector<WP<CDRMLeaseConnectorResource>> connectorsSent;
8889

8990
WP<CDRMLeaseDeviceResource> self;
91+
WP<CDRMLeaseProtocol> proto;
9092

9193
private:
9294
SP<CWpDrmLeaseDeviceV1> resource;
@@ -107,12 +109,14 @@ class CDRMLeaseDevice {
107109

108110
class CDRMLeaseProtocol : public IWaylandProtocol {
109111
public:
110-
CDRMLeaseProtocol(const wl_interface* iface, const int& ver, const std::string& name);
112+
CDRMLeaseProtocol(const wl_interface* iface, const int& ver, const std::string& name, SP<Aquamarine::IBackendImplementation> drm);
111113

112114
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
113115

114116
void offer(PHLMONITOR monitor);
115117

118+
SP<Aquamarine::IBackendImplementation> getBackend();
119+
116120
private:
117121
void destroyResource(CDRMLeaseDeviceResource* resource);
118122
void destroyResource(CDRMLeaseConnectorResource* resource);
@@ -126,6 +130,7 @@ class CDRMLeaseProtocol : public IWaylandProtocol {
126130
std::vector<SP<CDRMLeaseResource>> m_vLeases;
127131

128132
SP<CDRMLeaseDevice> primaryDevice;
133+
WP<CDRMLeaseProtocol> self;
129134

130135
friend class CDRMLeaseDeviceResource;
131136
friend class CDRMLeaseConnectorResource;
@@ -134,5 +139,5 @@ class CDRMLeaseProtocol : public IWaylandProtocol {
134139
};
135140

136141
namespace PROTO {
137-
inline UP<CDRMLeaseProtocol> lease;
142+
inline std::vector<UP<CDRMLeaseProtocol>> lease;
138143
};

0 commit comments

Comments
 (0)