mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-12-22 11:39:49 +01:00
drm: clearer flow when rescanning connectors (#113)
* consolidates into checkOutput for clearer flow when rescanning connectors * add error log
This commit is contained in:
parent
7dea26bba0
commit
1af9816244
2 changed files with 52 additions and 33 deletions
|
@ -375,9 +375,10 @@ namespace Aquamarine {
|
||||||
bool initMgpu();
|
bool initMgpu();
|
||||||
bool grabFormats();
|
bool grabFormats();
|
||||||
bool shouldBlit();
|
bool shouldBlit();
|
||||||
void scanConnectors(bool allowConnect = true);
|
void scanConnectors();
|
||||||
void scanLeases();
|
void scanLeases();
|
||||||
void restoreAfterVT();
|
void restoreAfterVT();
|
||||||
|
void recheckOutputs();
|
||||||
void recheckCRTCs();
|
void recheckCRTCs();
|
||||||
void buildGlFormats(const std::vector<SGLFormat>& fmts);
|
void buildGlFormats(const std::vector<SGLFormat>& fmts);
|
||||||
|
|
||||||
|
|
|
@ -243,9 +243,7 @@ std::vector<SP<CDRMBackend>> Aquamarine::CDRMBackend::attempt(SP<CBackend> backe
|
||||||
|
|
||||||
drmBackend->grabFormats();
|
drmBackend->grabFormats();
|
||||||
|
|
||||||
drmBackend->scanConnectors(false);
|
drmBackend->recheckOutputs();
|
||||||
|
|
||||||
drmBackend->recheckCRTCs();
|
|
||||||
|
|
||||||
if (!newPrimary) {
|
if (!newPrimary) {
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: gpu {} becomes primary drm", gpu->path));
|
backend->log(AQ_LOG_DEBUG, std::format("drm: gpu {} becomes primary drm", gpu->path));
|
||||||
|
@ -278,8 +276,7 @@ bool Aquamarine::CDRMBackend::sessionActive() {
|
||||||
void Aquamarine::CDRMBackend::restoreAfterVT() {
|
void Aquamarine::CDRMBackend::restoreAfterVT() {
|
||||||
backend->log(AQ_LOG_DEBUG, "drm: Restoring after VT switch");
|
backend->log(AQ_LOG_DEBUG, "drm: Restoring after VT switch");
|
||||||
|
|
||||||
scanConnectors(false);
|
recheckOutputs();
|
||||||
recheckCRTCs();
|
|
||||||
|
|
||||||
backend->log(AQ_LOG_DEBUG, "drm: Rescanned connectors");
|
backend->log(AQ_LOG_DEBUG, "drm: Rescanned connectors");
|
||||||
|
|
||||||
|
@ -617,21 +614,11 @@ void Aquamarine::CDRMBackend::recheckCRTCs() {
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} is not connected{}", c->szName, c->crtc ? std::format(", removing old crtc {}", c->crtc->id) : ""));
|
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} is not connected{}", c->szName, c->crtc ? std::format(", removing old crtc {}", c->crtc->id) : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if any connectors get a crtc and are connected, we need to rescan to assign them outputs.
|
// tell the user to re-assign a valid mode etc, if needed
|
||||||
bool rescan = false;
|
for (auto const& conn : changed) {
|
||||||
for (auto const& c : changed) {
|
if (conn->status != DRM_MODE_CONNECTED && conn->output)
|
||||||
if (!c->output && c->status == DRM_MODE_CONNECTED) {
|
conn->output->events.state.emit(IOutput::SStateEvent{});
|
||||||
rescan = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// tell the user to re-assign a valid mode etc
|
|
||||||
if (c->output)
|
|
||||||
c->output->events.state.emit(IOutput::SStateEvent{});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
backend->log(AQ_LOG_DEBUG, "drm: rescanning after realloc");
|
|
||||||
scanConnectors();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Aquamarine::CDRMBackend::grabFormats() {
|
bool Aquamarine::CDRMBackend::grabFormats() {
|
||||||
|
@ -662,8 +649,7 @@ bool Aquamarine::CDRMBackend::registerGPU(SP<CSessionDevice> gpu_, SP<CDRMBacken
|
||||||
auto E = std::any_cast<CSessionDevice::SChangeEvent>(d);
|
auto E = std::any_cast<CSessionDevice::SChangeEvent>(d);
|
||||||
if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_HOTPLUG) {
|
if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_HOTPLUG) {
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: Got a hotplug event for {}", gpuName));
|
backend->log(AQ_LOG_DEBUG, std::format("drm: Got a hotplug event for {}", gpuName));
|
||||||
scanConnectors(false);
|
recheckOutputs();
|
||||||
recheckCRTCs();
|
|
||||||
} else if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_LEASE) {
|
} else if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_LEASE) {
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: Got a lease event for {}", gpuName));
|
backend->log(AQ_LOG_DEBUG, std::format("drm: Got a lease event for {}", gpuName));
|
||||||
scanLeases();
|
scanLeases();
|
||||||
|
@ -680,7 +666,39 @@ eBackendType Aquamarine::CDRMBackend::type() {
|
||||||
return eBackendType::AQ_BACKEND_DRM;
|
return eBackendType::AQ_BACKEND_DRM;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aquamarine::CDRMBackend::scanConnectors(bool allowConnect) {
|
void Aquamarine::CDRMBackend::recheckOutputs() {
|
||||||
|
scanConnectors();
|
||||||
|
|
||||||
|
// disconnect now to possibly free up crtcs
|
||||||
|
for (const auto& conn : connectors) {
|
||||||
|
if (conn->status != DRM_MODE_CONNECTED && conn->output) {
|
||||||
|
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} disconnected", conn->szName));
|
||||||
|
conn->disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
recheckCRTCs();
|
||||||
|
|
||||||
|
// now that crtcs are assigned, connect outputs
|
||||||
|
for (const auto& conn : connectors) {
|
||||||
|
if (conn->status == DRM_MODE_CONNECTED && !conn->output) {
|
||||||
|
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} connected", conn->szName));
|
||||||
|
|
||||||
|
auto drmConn = drmModeGetConnector(gpu->fd, conn->id);
|
||||||
|
|
||||||
|
// ??? was valid 5 sec ago...
|
||||||
|
if (!drmConn) {
|
||||||
|
backend->log(AQ_LOG_ERROR, std::format("drm: Connector {} couldn't be connected, drm connector id is no longer valid??", conn->szName));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn->connect(drmConn);
|
||||||
|
drmModeFreeConnector(drmConn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aquamarine::CDRMBackend::scanConnectors() {
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: Scanning connectors for {}", gpu->path));
|
backend->log(AQ_LOG_DEBUG, std::format("drm: Scanning connectors for {}", gpu->path));
|
||||||
|
|
||||||
auto resources = drmModeGetResources(gpu->fd);
|
auto resources = drmModeGetResources(gpu->fd);
|
||||||
|
@ -726,19 +744,19 @@ void Aquamarine::CDRMBackend::scanConnectors(bool allowConnect) {
|
||||||
|
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} connection state: {}", connectorID, (int)drmConn->connection));
|
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} connection state: {}", connectorID, (int)drmConn->connection));
|
||||||
|
|
||||||
if (allowConnect) {
|
|
||||||
if (conn->status == DRM_MODE_CONNECTED && !conn->output) {
|
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} connected", conn->szName));
|
|
||||||
conn->connect(drmConn);
|
|
||||||
} else if (conn->status != DRM_MODE_CONNECTED && conn->output) {
|
|
||||||
backend->log(AQ_LOG_DEBUG, std::format("drm: Connector {} disconnected", conn->szName));
|
|
||||||
conn->disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drmModeFreeConnector(drmConn);
|
drmModeFreeConnector(drmConn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cleanup hot unplugged connectors
|
||||||
|
std::erase_if(connectors, [resources](const auto& conn) {
|
||||||
|
for (size_t i = 0; i < resources->count_connectors; ++i) {
|
||||||
|
if (resources->connectors[i] == conn->id)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
drmModeFreeResources(resources);
|
drmModeFreeResources(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue