@@ -10,12 +10,18 @@ CDRMLeaseResource::CDRMLeaseResource(SP<CWpDrmLeaseV1> resource_, SP<CDRMLeaseRe
10
10
if UNLIKELY (!good ())
11
11
return ;
12
12
13
- resource->setOnDestroy ([this ](CWpDrmLeaseV1* r) { PROTO::lease->destroyResource (this ); });
14
- resource->setDestroy ([this ](CWpDrmLeaseV1* r) { PROTO::lease->destroyResource (this ); });
15
-
16
13
parent = request->parent ;
17
14
requested = request->requested ;
18
15
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
+
19
25
for (auto const & m : requested) {
20
26
if (!m->monitor || m->monitor ->isBeingLeased ) {
21
27
LOGM (ERR, " Rejecting lease: no monitor or monitor is being leased for {}" , (m->monitor ? m->monitor ->szName : " null" ));
@@ -82,11 +88,11 @@ CDRMLeaseResource::~CDRMLeaseResource() {
82
88
listeners.destroyLease .reset ();
83
89
}
84
90
85
- CDRMLeaseRequestResource::CDRMLeaseRequestResource (SP<CWpDrmLeaseRequestV1> resource_) : resource(resource_) {
91
+ CDRMLeaseRequestResource::CDRMLeaseRequestResource (WP<CDRMLeaseDeviceResource> parent_, SP<CWpDrmLeaseRequestV1> resource_) : parent(parent_), resource(resource_) {
86
92
if UNLIKELY (!good ())
87
93
return ;
88
94
89
- resource->setOnDestroy ([this ](CWpDrmLeaseRequestV1* r) { PROTO::lease ->destroyResource (this ); });
95
+ resource->setOnDestroy ([this ](CWpDrmLeaseRequestV1* r) { parent-> proto ->destroyResource (this ); });
90
96
91
97
resource->setRequestConnector ([this ](CWpDrmLeaseRequestV1* r, wl_resource* conn) {
92
98
if (!conn) {
@@ -118,10 +124,10 @@ CDRMLeaseRequestResource::CDRMLeaseRequestResource(SP<CWpDrmLeaseRequestV1> reso
118
124
return ;
119
125
}
120
126
121
- PROTO::lease ->m_vLeases .emplace_back (RESOURCE);
127
+ parent-> proto ->m_vLeases .emplace_back (RESOURCE);
122
128
123
129
// per protcol, after submit, this is dead.
124
- PROTO::lease ->destroyResource (this );
130
+ parent-> proto ->destroyResource (this );
125
131
});
126
132
}
127
133
@@ -134,12 +140,19 @@ SP<CDRMLeaseConnectorResource> CDRMLeaseConnectorResource::fromResource(wl_resou
134
140
return data ? data->self .lock () : nullptr ;
135
141
}
136
142
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_) {
138
145
if UNLIKELY (!good ())
139
146
return ;
140
147
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
+ });
143
156
144
157
resource->setData (this );
145
158
@@ -163,30 +176,31 @@ void CDRMLeaseConnectorResource::sendData() {
163
176
resource->sendDone ();
164
177
}
165
178
166
- CDRMLeaseDeviceResource::CDRMLeaseDeviceResource (SP<CWpDrmLeaseDeviceV1> resource_) : resource(resource_) {
179
+ CDRMLeaseDeviceResource::CDRMLeaseDeviceResource (WP<CDRMLeaseProtocol> proto_, SP<CWpDrmLeaseDeviceV1> resource_) : proto(proto_), resource(resource_) {
167
180
if UNLIKELY (!good ())
168
181
return ;
169
182
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 ); });
172
185
173
186
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));
175
188
if UNLIKELY (!RESOURCE) {
176
189
resource->noMemory ();
177
190
return ;
178
191
}
179
192
180
193
RESOURCE->self = RESOURCE;
181
194
182
- PROTO::lease ->m_vRequests .emplace_back (RESOURCE);
195
+ proto ->m_vRequests .emplace_back (RESOURCE);
183
196
184
197
LOGM (LOG, " New lease request {}" , id);
185
198
186
199
RESOURCE->parent = self;
187
200
});
188
201
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 ()};
190
204
if (!fd.isValid ()) {
191
205
LOGM (ERR, " Failed to dup fd in lease" );
192
206
return ;
@@ -195,7 +209,7 @@ CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP<CWpDrmLeaseDeviceV1> resourc
195
209
LOGM (LOG, " Sending DRMFD {} to new lease device" , fd.get ());
196
210
resource->sendDrmFd (fd.get ());
197
211
198
- for (auto const & m : PROTO::lease-> primaryDevice ->offeredOutputs ) {
212
+ for (auto const & m : primaryDevice->offeredOutputs ) {
199
213
if (m)
200
214
sendConnector (m.lock ());
201
215
}
@@ -211,7 +225,7 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) {
211
225
if (std::find_if (connectorsSent.begin (), connectorsSent.end (), [monitor](const auto & e) { return e && !e->dead && e->monitor == monitor; }) != connectorsSent.end ())
212
226
return ;
213
227
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);
215
229
if UNLIKELY (!RESOURCE) {
216
230
resource->noMemory ();
217
231
return ;
@@ -223,7 +237,7 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) {
223
237
LOGM (LOG, " Sending new connector {}" , monitor->szName );
224
238
225
239
connectorsSent.emplace_back (RESOURCE);
226
- PROTO::lease ->m_vConnectors .emplace_back (RESOURCE);
240
+ proto ->m_vConnectors .emplace_back (RESOURCE);
227
241
228
242
resource->sendConnector (RESOURCE->resource .get ());
229
243
@@ -244,25 +258,28 @@ CDRMLeaseDevice::CDRMLeaseDevice(SP<Aquamarine::CDRMBackend> drmBackend) : backe
244
258
name = drm->gpuName ;
245
259
}
246
260
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
+ }
253
268
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);
255
273
256
- if (primaryDevice->success )
257
- break ;
274
+ if (! primaryDevice || !primaryDevice ->success ) {
275
+ g_pEventLoopManager-> doLater ([ this ]() { findCDRMLeaseProtocolAndDo ( this , []( auto & lease) { lease. reset (); }); }) ;
258
276
}
259
-
260
- if (!primaryDevice || !primaryDevice->success )
261
- g_pEventLoopManager->doLater ([]() { PROTO::lease.reset (); });
262
277
}
263
278
264
279
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)));
266
283
267
284
if UNLIKELY (!RESOURCE->good ()) {
268
285
wl_client_post_no_memory (client);
@@ -292,14 +309,16 @@ void CDRMLeaseProtocol::destroyResource(CDRMLeaseResource* resource) {
292
309
std::erase_if (m_vLeases, [resource](const auto & e) { return e.get () == resource; });
293
310
}
294
311
312
+ SP<Aquamarine::IBackendImplementation> CDRMLeaseProtocol::getBackend () {
313
+ return primaryDevice->backend ;
314
+ }
315
+
295
316
void CDRMLeaseProtocol::offer (PHLMONITOR monitor) {
296
317
std::erase_if (primaryDevice->offeredOutputs , [](const auto & e) { return e.expired (); });
297
318
if (std::find (primaryDevice->offeredOutputs .begin (), primaryDevice->offeredOutputs .end (), monitor) != primaryDevice->offeredOutputs .end ())
298
319
return ;
299
-
300
320
if (monitor->output ->getBackend ()->type () != Aquamarine::AQ_BACKEND_DRM)
301
321
return ;
302
-
303
322
if (monitor->output ->getBackend () != primaryDevice->backend ) {
304
323
LOGM (ERR, " Monitor {} cannot be leased: primaryDevice lease is for a different device" , monitor->szName );
305
324
return ;
0 commit comments