mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-17 04:56:00 +01:00
drm: recheck CRTCs after launch and reset
This commit is contained in:
parent
dc1181a65e
commit
56e7659ad8
4 changed files with 80 additions and 4 deletions
|
@ -345,6 +345,7 @@ namespace Aquamarine {
|
||||||
void scanConnectors();
|
void scanConnectors();
|
||||||
void scanLeases();
|
void scanLeases();
|
||||||
void restoreAfterVT();
|
void restoreAfterVT();
|
||||||
|
void recheckCRTCs();
|
||||||
|
|
||||||
Hyprutils::Memory::CSharedPointer<CSessionDevice> gpu;
|
Hyprutils::Memory::CSharedPointer<CSessionDevice> gpu;
|
||||||
Hyprutils::Memory::CSharedPointer<IDRMImplementation> impl;
|
Hyprutils::Memory::CSharedPointer<IDRMImplementation> impl;
|
||||||
|
|
|
@ -148,7 +148,7 @@ namespace Aquamarine {
|
||||||
AQ_OUTPUT_PRESENT_ZEROCOPY = (1 << 3),
|
AQ_OUTPUT_PRESENT_ZEROCOPY = (1 << 3),
|
||||||
};
|
};
|
||||||
struct SStateEvent {
|
struct SStateEvent {
|
||||||
Hyprutils::Math::Vector2D size;
|
Hyprutils::Math::Vector2D size; // if {0,0}, means it needs a reconfigure.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SPresentEvent {
|
struct SPresentEvent {
|
||||||
|
|
|
@ -146,9 +146,9 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
|
||||||
|
|
||||||
auto modName = drmGetFormatModifierName(attrs.modifier);
|
auto modName = drmGetFormatModifierName(attrs.modifier);
|
||||||
|
|
||||||
allocator->backend->log(
|
allocator->backend->log(AQ_LOG_DEBUG,
|
||||||
AQ_LOG_DEBUG,
|
std::format("GBM: Allocated a new buffer with size {} and format {} with modifier {} aka {}", attrs.size, fourccToName(attrs.format), attrs.modifier,
|
||||||
std::format("GBM: Allocated a new buffer with size {} and format {} with modifier {}", attrs.size, fourccToName(attrs.format), modName ? modName : "Unknown"));
|
modName ? modName : "Unknown"));
|
||||||
|
|
||||||
free(modName);
|
free(modName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,6 +228,8 @@ std::vector<SP<CDRMBackend>> Aquamarine::CDRMBackend::attempt(SP<CBackend> backe
|
||||||
|
|
||||||
drmBackend->scanConnectors();
|
drmBackend->scanConnectors();
|
||||||
|
|
||||||
|
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));
|
||||||
newPrimary = drmBackend;
|
newPrimary = drmBackend;
|
||||||
|
@ -255,6 +257,7 @@ 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();
|
scanConnectors();
|
||||||
|
recheckCRTCs();
|
||||||
|
|
||||||
backend->log(AQ_LOG_DEBUG, "drm: Rescanned connectors");
|
backend->log(AQ_LOG_DEBUG, "drm: Rescanned connectors");
|
||||||
|
|
||||||
|
@ -449,6 +452,78 @@ bool Aquamarine::CDRMBackend::initResources() {
|
||||||
return true;
|
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() {
|
bool Aquamarine::CDRMBackend::grabFormats() {
|
||||||
// FIXME: do this properly maybe?
|
// FIXME: do this properly maybe?
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in a new issue