Skip to content

Commit

Permalink
drm: recheck CRTCs after launch and reset
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed Jul 8, 2024
1 parent dc1181a commit 56e7659
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 4 deletions.
1 change: 1 addition & 0 deletions include/aquamarine/backend/DRM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ namespace Aquamarine {
void scanConnectors();
void scanLeases();
void restoreAfterVT();
void recheckCRTCs();

Hyprutils::Memory::CSharedPointer<CSessionDevice> gpu;
Hyprutils::Memory::CSharedPointer<IDRMImplementation> impl;
Expand Down
2 changes: 1 addition & 1 deletion include/aquamarine/output/Output.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ namespace Aquamarine {
AQ_OUTPUT_PRESENT_ZEROCOPY = (1 << 3),
};
struct SStateEvent {
Hyprutils::Math::Vector2D size;
Hyprutils::Math::Vector2D size; // if {0,0}, means it needs a reconfigure.
};

struct SPresentEvent {
Expand Down
6 changes: 3 additions & 3 deletions src/allocator/GBM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,9 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti

auto modName = drmGetFormatModifierName(attrs.modifier);

allocator->backend->log(
AQ_LOG_DEBUG,
std::format("GBM: Allocated a new buffer with size {} and format {} with modifier {}", attrs.size, fourccToName(attrs.format), modName ? modName : "Unknown"));
allocator->backend->log(AQ_LOG_DEBUG,
std::format("GBM: Allocated a new buffer with size {} and format {} with modifier {} aka {}", attrs.size, fourccToName(attrs.format), attrs.modifier,
modName ? modName : "Unknown"));

free(modName);
}
Expand Down
75 changes: 75 additions & 0 deletions src/backend/drm/DRM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ std::vector<SP<CDRMBackend>> Aquamarine::CDRMBackend::attempt(SP<CBackend> backe

drmBackend->scanConnectors();

drmBackend->recheckCRTCs();

if (!newPrimary) {
backend->log(AQ_LOG_DEBUG, std::format("drm: gpu {} becomes primary drm", gpu->path));
newPrimary = drmBackend;
Expand Down Expand Up @@ -255,6 +257,7 @@ void Aquamarine::CDRMBackend::restoreAfterVT() {
backend->log(AQ_LOG_DEBUG, "drm: Restoring after VT switch");

scanConnectors();
recheckCRTCs();

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

Expand Down Expand Up @@ -449,6 +452,78 @@ bool Aquamarine::CDRMBackend::initResources() {
return true;
}

void Aquamarine::CDRMBackend::recheckCRTCs() {
if (connectors.empty() || crtcs.empty())
return;

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

std::vector<SP<SDRMConnector>> recheck, changed;
for (auto& c : connectors) {
if (c->crtc && c->status == DRM_MODE_CONNECTED) {
backend->log(AQ_LOG_DEBUG, std::format("drm: Skipping connector {}, has crtc {} and is connected", c->szName, c->crtc->id));
continue;
}

recheck.emplace_back(c);
backend->log(AQ_LOG_DEBUG, std::format("drm: connector {}, has crtc {}, will be rechecked", c->szName, c->crtc ? c->crtc->id : -1));
}

for (size_t i = 0; i < crtcs.size(); ++i) {
bool taken = false;
for (auto& c : connectors) {
if (c->crtc != crtcs.at(i))
continue;

if (c->status != DRM_MODE_CONNECTED)
continue;

backend->log(AQ_LOG_DEBUG, std::format("drm: slot {} crtc {} taken by {}, skipping", i, c->crtc->id, c->szName));
taken = true;
break;
}

if (taken)
continue;

bool assigned = false;
for (auto& c : recheck) {
if (!(c->possibleCrtcs & (1 << i)))
continue;

// deactivate old output
if (c->output && c->output->state && c->output->state->state().enabled) {
c->output->state->setEnabled(false);
c->output->commit();
}

c->crtc = crtcs.at(i);
backend->log(AQ_LOG_DEBUG, std::format("drm: slot {} crtc {} assigned to {} (old {})", i, crtcs.at(i)->id, c->szName, c->crtc ? c->crtc->id : -1));
assigned = true;
changed.emplace_back(c);
break;
}

if (!assigned)
backend->log(AQ_LOG_DEBUG, std::format("drm: slot {} crtc {} unassigned", i, crtcs.at(i)->id));
}

// if any connectors get a crtc and are connected, we need to rescan to assign them outputs.
bool rescan = false;
for (auto& c : changed) {
if (!c->output && c->status == DRM_MODE_CONNECTED) {
rescan = true;
continue;
}

// tell the user to re-assign a valid mode etc
c->output->events.state.emit(IOutput::SStateEvent{});
}

if (rescan)
scanConnectors();
}

bool Aquamarine::CDRMBackend::grabFormats() {
// FIXME: do this properly maybe?
return true;
Expand Down

0 comments on commit 56e7659

Please sign in to comment.