@@ -10,12 +10,12 @@ 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) { if (parent.valid ()) parent->proto ->destroyResource (this ); });
17
+ resource->setDestroy ([this ](CWpDrmLeaseV1* r) { if (parent.valid ()) parent->proto ->destroyResource (this ); });
18
+
19
19
for (auto const & m : requested) {
20
20
if (!m->monitor || m->monitor ->isBeingLeased ) {
21
21
LOGM (ERR, " Rejecting lease: no monitor or monitor is being leased for {}" , (m->monitor ? m->monitor ->szName : " null" ));
@@ -82,11 +82,11 @@ CDRMLeaseResource::~CDRMLeaseResource() {
82
82
listeners.destroyLease .reset ();
83
83
}
84
84
85
- CDRMLeaseRequestResource::CDRMLeaseRequestResource (SP<CWpDrmLeaseRequestV1> resource_) : resource(resource_) {
85
+ CDRMLeaseRequestResource::CDRMLeaseRequestResource (WP<CDRMLeaseDeviceResource> parent_, SP<CWpDrmLeaseRequestV1> resource_) : parent(parent_), resource(resource_) {
86
86
if UNLIKELY (!good ())
87
87
return ;
88
88
89
- resource->setOnDestroy ([this ](CWpDrmLeaseRequestV1* r) { PROTO::lease ->destroyResource (this ); });
89
+ resource->setOnDestroy ([this ](CWpDrmLeaseRequestV1* r) { parent-> proto ->destroyResource (this ); });
90
90
91
91
resource->setRequestConnector ([this ](CWpDrmLeaseRequestV1* r, wl_resource* conn) {
92
92
if (!conn) {
@@ -118,10 +118,10 @@ CDRMLeaseRequestResource::CDRMLeaseRequestResource(SP<CWpDrmLeaseRequestV1> reso
118
118
return ;
119
119
}
120
120
121
- PROTO::lease ->m_vLeases .emplace_back (RESOURCE);
121
+ parent-> proto ->m_vLeases .emplace_back (RESOURCE);
122
122
123
123
// per protcol, after submit, this is dead.
124
- PROTO::lease ->destroyResource (this );
124
+ parent-> proto ->destroyResource (this );
125
125
});
126
126
}
127
127
@@ -134,12 +134,12 @@ SP<CDRMLeaseConnectorResource> CDRMLeaseConnectorResource::fromResource(wl_resou
134
134
return data ? data->self .lock () : nullptr ;
135
135
}
136
136
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_) {
138
138
if UNLIKELY (!good ())
139
139
return ;
140
140
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 ); });
143
143
144
144
resource->setData (this );
145
145
@@ -163,30 +163,31 @@ void CDRMLeaseConnectorResource::sendData() {
163
163
resource->sendDone ();
164
164
}
165
165
166
- CDRMLeaseDeviceResource::CDRMLeaseDeviceResource (SP<CWpDrmLeaseDeviceV1> resource_) : resource(resource_) {
166
+ CDRMLeaseDeviceResource::CDRMLeaseDeviceResource (WP<CDRMLeaseProtocol> proto_, SP<CWpDrmLeaseDeviceV1> resource_) : proto(proto_), resource(resource_) {
167
167
if UNLIKELY (!good ())
168
168
return ;
169
169
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 ); });
172
172
173
173
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));
175
175
if UNLIKELY (!RESOURCE) {
176
176
resource->noMemory ();
177
177
return ;
178
178
}
179
179
180
180
RESOURCE->self = RESOURCE;
181
181
182
- PROTO::lease ->m_vRequests .emplace_back (RESOURCE);
182
+ proto ->m_vRequests .emplace_back (RESOURCE);
183
183
184
184
LOGM (LOG, " New lease request {}" , id);
185
185
186
186
RESOURCE->parent = self;
187
187
});
188
188
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 ()};
190
191
if (!fd.isValid ()) {
191
192
LOGM (ERR, " Failed to dup fd in lease" );
192
193
return ;
@@ -195,7 +196,7 @@ CDRMLeaseDeviceResource::CDRMLeaseDeviceResource(SP<CWpDrmLeaseDeviceV1> resourc
195
196
LOGM (LOG, " Sending DRMFD {} to new lease device" , fd.get ());
196
197
resource->sendDrmFd (fd.get ());
197
198
198
- for (auto const & m : PROTO::lease-> primaryDevice ->offeredOutputs ) {
199
+ for (auto const & m : primaryDevice->offeredOutputs ) {
199
200
if (m)
200
201
sendConnector (m.lock ());
201
202
}
@@ -211,7 +212,7 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) {
211
212
if (std::find_if (connectorsSent.begin (), connectorsSent.end (), [monitor](const auto & e) { return e && !e->dead && e->monitor == monitor; }) != connectorsSent.end ())
212
213
return ;
213
214
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);
215
216
if UNLIKELY (!RESOURCE) {
216
217
resource->noMemory ();
217
218
return ;
@@ -223,7 +224,7 @@ void CDRMLeaseDeviceResource::sendConnector(PHLMONITOR monitor) {
223
224
LOGM (LOG, " Sending new connector {}" , monitor->szName );
224
225
225
226
connectorsSent.emplace_back (RESOURCE);
226
- PROTO::lease ->m_vConnectors .emplace_back (RESOURCE);
227
+ proto ->m_vConnectors .emplace_back (RESOURCE);
227
228
228
229
resource->sendConnector (RESOURCE->resource .get ());
229
230
@@ -244,25 +245,26 @@ CDRMLeaseDevice::CDRMLeaseDevice(SP<Aquamarine::CDRMBackend> drmBackend) : backe
244
245
name = drm->gpuName ;
245
246
}
246
247
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
+ }
253
254
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);
255
258
256
- if (primaryDevice->success )
257
- break ;
259
+ if (! primaryDevice || !primaryDevice ->success ) {
260
+ g_pEventLoopManager-> doLater ([ this ]() { findCDRMLeaseProtocolAndDo ( this , []( auto &lease) {lease. reset ();}); }) ;
258
261
}
259
-
260
- if (!primaryDevice || !primaryDevice->success )
261
- g_pEventLoopManager->doLater ([]() { PROTO::lease.reset (); });
262
262
}
263
263
264
264
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)));
266
268
267
269
if UNLIKELY (!RESOURCE->good ()) {
268
270
wl_client_post_no_memory (client);
@@ -292,14 +294,16 @@ void CDRMLeaseProtocol::destroyResource(CDRMLeaseResource* resource) {
292
294
std::erase_if (m_vLeases, [resource](const auto & e) { return e.get () == resource; });
293
295
}
294
296
297
+ SP<Aquamarine::IBackendImplementation> CDRMLeaseProtocol::getBackend () {
298
+ return primaryDevice->backend ;
299
+ }
300
+
295
301
void CDRMLeaseProtocol::offer (PHLMONITOR monitor) {
296
302
std::erase_if (primaryDevice->offeredOutputs , [](const auto & e) { return e.expired (); });
297
303
if (std::find (primaryDevice->offeredOutputs .begin (), primaryDevice->offeredOutputs .end (), monitor) != primaryDevice->offeredOutputs .end ())
298
304
return ;
299
-
300
305
if (monitor->output ->getBackend ()->type () != Aquamarine::AQ_BACKEND_DRM)
301
306
return ;
302
-
303
307
if (monitor->output ->getBackend () != primaryDevice->backend ) {
304
308
LOGM (ERR, " Monitor {} cannot be leased: primaryDevice lease is for a different device" , monitor->szName );
305
309
return ;
0 commit comments