Skip to content

Commit 87fc281

Browse files
drm-lease: Add Multi-GPU Support
1 parent 225e13c commit 87fc281

File tree

4 files changed

+73
-45
lines changed

4 files changed

+73
-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: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,18 @@ 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) {
17+
if (parent.valid())
18+
parent->proto->destroyResource(this);
19+
});
20+
resource->setDestroy([this](CWpDrmLeaseV1* r) {
21+
if (parent.valid())
22+
parent->proto->destroyResource(this);
23+
});
24+
1925
for (auto const& m : requested) {
2026
if (!m->monitor || m->monitor->isBeingLeased) {
2127
LOGM(ERR, "Rejecting lease: no monitor or monitor is being leased for {}", (m->monitor ? m->monitor->szName : "null"));
@@ -82,11 +88,11 @@ CDRMLeaseResource::~CDRMLeaseResource() {
8288
listeners.destroyLease.reset();
8389
}
8490

85-
CDRMLeaseRequestResource::CDRMLeaseRequestResource(SP<CWpDrmLeaseRequestV1> resource_) : resource(resource_) {
91+
CDRMLeaseRequestResource::CDRMLeaseRequestResource(WP<CDRMLeaseDeviceResource> parent_, SP<CWpDrmLeaseRequestV1> resource_) : parent(parent_), resource(resource_) {
8692
if UNLIKELY (!good())
8793
return;
8894

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

9197
resource->setRequestConnector([this](CWpDrmLeaseRequestV1* r, wl_resource* conn) {
9298
if (!conn) {
@@ -118,10 +124,10 @@ CDRMLeaseRequestResource::CDRMLeaseRequestResource(SP<CWpDrmLeaseRequestV1> reso
118124
return;
119125
}
120126

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

123129
// per protcol, after submit, this is dead.
124-
PROTO::lease->destroyResource(this);
130+
parent->proto->destroyResource(this);
125131
});
126132
}
127133

@@ -134,12 +140,19 @@ SP<CDRMLeaseConnectorResource> CDRMLeaseConnectorResource::fromResource(wl_resou
134140
return data ? data->self.lock() : nullptr;
135141
}
136142

137-
CDRMLeaseConnectorResource::CDRMLeaseConnectorResource(SP<CWpDrmLeaseConnectorV1> resource_, PHLMONITOR monitor_) : monitor(monitor_), resource(resource_) {
143+
CDRMLeaseConnectorResource::CDRMLeaseConnectorResource(WP<CDRMLeaseDeviceResource> parent_, SP<CWpDrmLeaseConnectorV1> resource_, PHLMONITOR monitor_) :
144+
parent(parent_), monitor(monitor_), resource(resource_) {
138145
if UNLIKELY (!good())
139146
return;
140147

141-
resource->setOnDestroy([this](CWpDrmLeaseConnectorV1* r) { PROTO::lease->destroyResource(this); });
142-
resource->setDestroy([this](CWpDrmLeaseConnectorV1* r) { PROTO::lease->destroyResource(this); });
148+
resource->setOnDestroy([this](CWpDrmLeaseConnectorV1* r) {
149+
if (parent.valid())
150+
parent->proto->destroyResource(this);
151+
});
152+
resource->setDestroy([this](CWpDrmLeaseConnectorV1* r) {
153+
if (parent.valid())
154+
parent->proto->destroyResource(this);
155+
});
143156

144157
resource->setData(this);
145158

@@ -163,30 +176,31 @@ void CDRMLeaseConnectorResource::sendData() {
163176
resource->sendDone();
164177
}
165178

166-
CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP<CWpDrmLeaseDeviceV1> resource_) : resource(resource_) {
179+
CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(WP<CDRMLeaseProtocol> proto_, SP<CWpDrmLeaseDeviceV1> resource_) : proto(proto_), resource(resource_) {
167180
if UNLIKELY (!good())
168181
return;
169182

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

173186
resource->setCreateLeaseRequest([this](CWpDrmLeaseDeviceV1* r, uint32_t id) {
174-
auto RESOURCE = makeShared<CDRMLeaseRequestResource>(makeShared<CWpDrmLeaseRequestV1>(resource->client(), resource->version(), id));
187+
auto RESOURCE = makeShared<CDRMLeaseRequestResource>(self, makeShared<CWpDrmLeaseRequestV1>(resource->client(), resource->version(), id));
175188
if UNLIKELY (!RESOURCE) {
176189
resource->noMemory();
177190
return;
178191
}
179192

180193
RESOURCE->self = RESOURCE;
181194

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

184197
LOGM(LOG, "New lease request {}", id);
185198

186199
RESOURCE->parent = self;
187200
});
188201

189-
CFileDescriptor fd{((Aquamarine::CDRMBackend*)PROTO::lease->primaryDevice->backend.get())->getNonMasterFD()};
202+
auto& primaryDevice = proto->primaryDevice;
203+
CFileDescriptor fd{((Aquamarine::CDRMBackend*)primaryDevice->backend.get())->getNonMasterFD()};
190204
if (!fd.isValid()) {
191205
LOGM(ERR, "Failed to dup fd in lease");
192206
return;
@@ -195,7 +209,7 @@ CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP<CWpDrmLeaseDeviceV1> resourc
195209
LOGM(LOG, "Sending DRMFD {} to new lease device", fd.get());
196210
resource->sendDrmFd(fd.get());
197211

198-
for (auto const& m : PROTO::lease->primaryDevice->offeredOutputs) {
212+
for (auto const& m : primaryDevice->offeredOutputs) {
199213
if (m)
200214
sendConnector(m.lock());
201215
}
@@ -211,7 +225,7 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) {
211225
if (std::find_if(connectorsSent.begin(), connectorsSent.end(), [monitor](const auto& e) { return e && !e->dead && e->monitor == monitor; }) != connectorsSent.end())
212226
return;
213227

214-
auto RESOURCE = makeShared<CDRMLeaseConnectorResource>(makeShared<CWpDrmLeaseConnectorV1>(resource->client(), resource->version(), 0), monitor);
228+
auto RESOURCE = makeShared<CDRMLeaseConnectorResource>(self, makeShared<CWpDrmLeaseConnectorV1>(resource->client(), resource->version(), 0), monitor);
215229
if UNLIKELY (!RESOURCE) {
216230
resource->noMemory();
217231
return;
@@ -223,7 +237,7 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) {
223237
LOGM(LOG, "Sending new connector {}", monitor->szName);
224238

225239
connectorsSent.emplace_back(RESOURCE);
226-
PROTO::lease->m_vConnectors.emplace_back(RESOURCE);
240+
proto->m_vConnectors.emplace_back(RESOURCE);
227241

228242
resource->sendConnector(RESOURCE->resource.get());
229243

@@ -244,25 +258,28 @@ CDRMLeaseDevice::CDRMLeaseDevice(SP<Aquamarine::CDRMBackend> drmBackend) : backe
244258
name = drm->gpuName;
245259
}
246260

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();
261+
template <class UnaryPred>
262+
static void findCDRMLeaseProtocolAndDo(CDRMLeaseProtocol* self, UnaryPred pred) {
263+
auto ref = std::ranges::find_if(PROTO::lease.begin(), PROTO::lease.end(), [self](auto& e) { return e.get() == self; });
264+
if (ref != PROTO::lease.end()) {
265+
pred(*ref);
266+
}
267+
}
253268

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

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

264279
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)));
280+
findCDRMLeaseProtocolAndDo(this, [this](auto& lease) { self = WP<CDRMLeaseProtocol>(lease); });
281+
282+
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CDRMLeaseDeviceResource>(self, makeShared<CWpDrmLeaseDeviceV1>(client, ver, id)));
266283

267284
if UNLIKELY (!RESOURCE->good()) {
268285
wl_client_post_no_memory(client);
@@ -292,14 +309,16 @@ void CDRMLeaseProtocol::destroyResource(CDRMLeaseResource* resource) {
292309
std::erase_if(m_vLeases, [resource](const auto& e) { return e.get() == resource; });
293310
}
294311

312+
SP<Aquamarine::IBackendImplementation> CDRMLeaseProtocol::getBackend() {
313+
return primaryDevice->backend;
314+
}
315+
295316
void CDRMLeaseProtocol::offer(PHLMONITOR monitor) {
296317
std::erase_if(primaryDevice->offeredOutputs, [](const auto& e) { return e.expired(); });
297318
if (std::find(primaryDevice->offeredOutputs.begin(), primaryDevice->offeredOutputs.end(), monitor) != primaryDevice->offeredOutputs.end())
298319
return;
299-
300320
if (monitor->output->getBackend()->type() != Aquamarine::AQ_BACKEND_DRM)
301321
return;
302-
303322
if (monitor->output->getBackend() != primaryDevice->backend) {
304323
LOGM(ERR, "Monitor {} cannot be leased: primaryDevice lease is for a different device", monitor->szName);
305324
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)