Skip to content

Commit

Permalink
consolidates into checkOutput for clearer flow when rescanning connec…
Browse files Browse the repository at this point in the history
…tors
  • Loading branch information
ikalco committed Dec 7, 2024
1 parent 7dea26b commit 44c76ba
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 41 deletions.
13 changes: 7 additions & 6 deletions include/aquamarine/backend/DRM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,15 +375,16 @@ namespace Aquamarine {
bool initMgpu();
bool grabFormats();
bool shouldBlit();
void scanConnectors(bool allowConnect = true);
void scanConnectors();
void scanLeases();
void restoreAfterVT();
void recheckCRTCs();
void buildGlFormats(const std::vector<SGLFormat>& fmts);
void recheckOutputs();
std::vector<Hyprutils::Memory::CSharedPointer<SDRMConnector>> recheckCRTCs();
void buildGlFormats(const std::vector<SGLFormat>& fmts);

Hyprutils::Memory::CSharedPointer<CSessionDevice> gpu;
Hyprutils::Memory::CSharedPointer<IDRMImplementation> impl;
Hyprutils::Memory::CWeakPointer<CDRMBackend> primary;
Hyprutils::Memory::CSharedPointer<CSessionDevice> gpu;
Hyprutils::Memory::CSharedPointer<IDRMImplementation> impl;
Hyprutils::Memory::CWeakPointer<CDRMBackend> primary;

struct {
Hyprutils::Memory::CSharedPointer<IAllocator> allocator;
Expand Down
83 changes: 48 additions & 35 deletions src/backend/drm/DRM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,7 @@ std::vector<SP<CDRMBackend>> Aquamarine::CDRMBackend::attempt(SP<CBackend> backe

drmBackend->grabFormats();

drmBackend->scanConnectors(false);

drmBackend->recheckCRTCs();
drmBackend->recheckOutputs();

if (!newPrimary) {
backend->log(AQ_LOG_DEBUG, std::format("drm: gpu {} becomes primary drm", gpu->path));
Expand Down Expand Up @@ -278,8 +276,7 @@ bool Aquamarine::CDRMBackend::sessionActive() {
void Aquamarine::CDRMBackend::restoreAfterVT() {
backend->log(AQ_LOG_DEBUG, "drm: Restoring after VT switch");

scanConnectors(false);
recheckCRTCs();
recheckOutputs();

backend->log(AQ_LOG_DEBUG, "drm: Rescanned connectors");

Expand Down Expand Up @@ -547,9 +544,9 @@ void Aquamarine::CDRMBackend::buildGlFormats(const std::vector<SGLFormat>& fmts)
glFormats = result;
}

void Aquamarine::CDRMBackend::recheckCRTCs() {
std::vector<SP<SDRMConnector>> Aquamarine::CDRMBackend::recheckCRTCs() {
if (connectors.empty() || crtcs.empty())
return;
return {};

backend->log(AQ_LOG_DEBUG, "drm: Rechecking CRTCs");

Expand Down Expand Up @@ -617,21 +614,7 @@ 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) : ""));
}

// if any connectors get a crtc and are connected, we need to rescan to assign them outputs.
bool rescan = false;
for (auto const& c : changed) {
if (!c->output && c->status == DRM_MODE_CONNECTED) {
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();
return changed;
}

bool Aquamarine::CDRMBackend::grabFormats() {
Expand Down Expand Up @@ -662,8 +645,7 @@ bool Aquamarine::CDRMBackend::registerGPU(SP<CSessionDevice> gpu_, SP<CDRMBacken
auto E = std::any_cast<CSessionDevice::SChangeEvent>(d);
if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_HOTPLUG) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Got a hotplug event for {}", gpuName));
scanConnectors(false);
recheckCRTCs();
recheckOutputs();
} else if (E.type == CSessionDevice::AQ_SESSION_EVENT_CHANGE_LEASE) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Got a lease event for {}", gpuName));
scanLeases();
Expand All @@ -680,7 +662,38 @@ eBackendType Aquamarine::CDRMBackend::type() {
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();
}
}

auto changed = recheckCRTCs();

// tell the user to re-assign a valid mode etc, if needed
for (auto const& conn : changed) {
if (conn->status != DRM_MODE_CONNECTED && conn->output)
conn->output->events.state.emit(IOutput::SStateEvent{});
}

// 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);
conn->connect(drmConn);
drmModeFreeConnector(drmConn);
}
}
}

void Aquamarine::CDRMBackend::scanConnectors() {
backend->log(AQ_LOG_DEBUG, std::format("drm: Scanning connectors for {}", gpu->path));

auto resources = drmModeGetResources(gpu->fd);
Expand Down Expand Up @@ -726,19 +739,19 @@ void Aquamarine::CDRMBackend::scanConnectors(bool allowConnect) {

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);
}

// 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);
}

Expand Down

0 comments on commit 44c76ba

Please sign in to comment.