mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-17 04:56:00 +01:00
drm: add vt restore code and adaptive sync
This commit is contained in:
parent
2e0052a21d
commit
d44aaec26f
5 changed files with 84 additions and 6 deletions
|
@ -227,6 +227,7 @@ namespace Aquamarine {
|
|||
class IDRMImplementation {
|
||||
public:
|
||||
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data) = 0;
|
||||
virtual bool reset(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector) = 0;
|
||||
};
|
||||
|
||||
class CDRMBackend : public IBackendImplementation {
|
||||
|
@ -259,6 +260,7 @@ namespace Aquamarine {
|
|||
bool initResources();
|
||||
bool grabFormats();
|
||||
void scanConnectors();
|
||||
void restoreAfterVT();
|
||||
|
||||
Hyprutils::Memory::CSharedPointer<CSessionDevice> gpu;
|
||||
Hyprutils::Memory::CSharedPointer<IDRMImplementation> impl;
|
||||
|
@ -277,6 +279,10 @@ namespace Aquamarine {
|
|||
bool supportsAddFb2Modifiers = false;
|
||||
} drmProps;
|
||||
|
||||
struct {
|
||||
Hyprutils::Signal::CHyprSignalListener sessionActivate;
|
||||
} listeners;
|
||||
|
||||
friend class CBackend;
|
||||
friend class CDRMFB;
|
||||
friend class CDRMFBAttachment;
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Aquamarine {
|
|||
public:
|
||||
CDRMLegacyImpl(Hyprutils::Memory::CSharedPointer<CDRMBackend> backend_);
|
||||
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data);
|
||||
virtual bool reset(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace Aquamarine {
|
|||
bool enabled = false;
|
||||
bool adaptiveSync = false;
|
||||
eOutputPresentationMode presentationMode = AQ_OUTPUT_PRESENTATION_VSYNC;
|
||||
std::vector<uint16_t> gammaLut;
|
||||
std::vector<uint16_t> gammaLut; // Gamma lut in the format [r,g,b]+
|
||||
Hyprutils::Math::Vector2D lastModeSize;
|
||||
Hyprutils::Memory::CWeakPointer<SOutputMode> mode;
|
||||
Hyprutils::Memory::CSharedPointer<SOutputMode> customMode;
|
||||
|
@ -109,7 +109,7 @@ namespace Aquamarine {
|
|||
bool enabled = false;
|
||||
bool nonDesktop = false;
|
||||
eSubpixelMode subpixel = AQ_SUBPIXEL_NONE;
|
||||
bool vrrCapable = false;
|
||||
bool vrrCapable = false, vrrActive = false;
|
||||
bool needsFrame = false;
|
||||
|
||||
//
|
||||
|
|
|
@ -23,7 +23,12 @@ using namespace Hyprutils::Math;
|
|||
#define SP CSharedPointer
|
||||
|
||||
Aquamarine::CDRMBackend::CDRMBackend(SP<CBackend> backend_) : backend(backend_) {
|
||||
;
|
||||
listeners.sessionActivate = backend->session->events.changeActive.registerListener([this](std::any d) {
|
||||
if (backend->session->active) {
|
||||
// session got activated, we need to restore
|
||||
restoreAfterVT();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static udev_enumerate* enumDRMCards(udev* udev) {
|
||||
|
@ -206,6 +211,45 @@ bool Aquamarine::CDRMBackend::sessionActive() {
|
|||
return backend->session->active;
|
||||
}
|
||||
|
||||
void Aquamarine::CDRMBackend::restoreAfterVT() {
|
||||
backend->log(AQ_LOG_DEBUG, "drm: Restoring after VT switch");
|
||||
|
||||
for (auto& c : connectors) {
|
||||
if (!c->crtc)
|
||||
continue;
|
||||
|
||||
backend->log(AQ_LOG_DEBUG, std::format("drm: Resetting crtc {}", c->crtc->id));
|
||||
|
||||
if (!impl->reset(c))
|
||||
backend->log(AQ_LOG_ERROR, std::format("drm: crtc {} failed reset", c->crtc->id));
|
||||
}
|
||||
|
||||
for (auto& c : connectors) {
|
||||
if (!c->crtc)
|
||||
continue;
|
||||
|
||||
SDRMConnectorCommitData data = {
|
||||
.mainFB = nullptr,
|
||||
.modeset = true,
|
||||
.blocking = true,
|
||||
.flags = 0,
|
||||
.test = false,
|
||||
};
|
||||
|
||||
if (c->output->state->state().mode && c->output->state->state().mode->modeInfo.has_value())
|
||||
data.modeInfo = *c->output->state->state().mode->modeInfo;
|
||||
else
|
||||
data.calculateMode(c);
|
||||
|
||||
backend->log(AQ_LOG_DEBUG,
|
||||
std::format("drm: Restoring crtc {} with clock {} hdisplay {} vdisplay {} vrefresh {}", c->crtc->id, data.modeInfo.clock, data.modeInfo.hdisplay,
|
||||
data.modeInfo.vdisplay, data.modeInfo.vrefresh));
|
||||
|
||||
if (!impl->commit(c, data))
|
||||
backend->log(AQ_LOG_ERROR, std::format("drm: crtc {} failed restore", c->crtc->id));
|
||||
}
|
||||
}
|
||||
|
||||
bool Aquamarine::CDRMBackend::checkFeatures() {
|
||||
uint64_t curW = 0, curH = 0;
|
||||
if (drmGetCap(gpu->fd, DRM_CAP_CURSOR_WIDTH, &curW))
|
||||
|
|
|
@ -41,7 +41,6 @@ bool Aquamarine::CDRMLegacyImpl::commitInternal(Hyprutils::Memory::CSharedPointe
|
|||
mode = (drmModeModeInfo*)&data.modeInfo;
|
||||
}
|
||||
|
||||
connector->backend->backend->log(AQ_LOG_DEBUG, std::format("legacy drm: Modesetting CRTC, connectors: {}", connectors.size()));
|
||||
connector->backend->backend->log(
|
||||
AQ_LOG_DEBUG,
|
||||
std::format("legacy drm: Modesetting CRTC, mode: clock {} hdisplay {} vdisplay {} vrefresh {}", mode->clock, mode->hdisplay, mode->vdisplay, mode->vrefresh));
|
||||
|
@ -52,9 +51,25 @@ bool Aquamarine::CDRMLegacyImpl::commitInternal(Hyprutils::Memory::CSharedPointe
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: gamma
|
||||
if (STATE.committed & COutputState::eOutputStateProperties::AQ_OUTPUT_STATE_ADAPTIVE_SYNC) {
|
||||
if (STATE.adaptiveSync && !connector->canDoVrr) {
|
||||
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: connector {} can't do vrr", connector->id));
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Adaptive sync
|
||||
if (connector->crtc->props.vrr_enabled) {
|
||||
if (auto ret = drmModeObjectSetProperty(backend->gpu->fd, connector->crtc->id, DRM_MODE_OBJECT_CRTC, connector->crtc->props.vrr_enabled, (uint64_t)STATE.adaptiveSync);
|
||||
ret) {
|
||||
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: drmModeObjectSetProperty: vrr -> {} failed: {}", STATE.adaptiveSync, strerror(-ret)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
connector->output->vrrActive = STATE.adaptiveSync;
|
||||
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: connector {} vrr -> {}", connector->id, STATE.adaptiveSync));
|
||||
}
|
||||
|
||||
// TODO: gamma
|
||||
|
||||
// TODO: cursor plane
|
||||
if (drmModeSetCursor(connector->backend->gpu->fd, connector->crtc->id, 0, 0, 0))
|
||||
|
@ -85,4 +100,16 @@ bool Aquamarine::CDRMLegacyImpl::commit(Hyprutils::Memory::CSharedPointer<SDRMCo
|
|||
return false;
|
||||
|
||||
return commitInternal(connector, data);
|
||||
}
|
||||
|
||||
bool Aquamarine::CDRMLegacyImpl::reset(SP<SDRMConnector> connector) {
|
||||
if (!connector->crtc)
|
||||
return true;
|
||||
|
||||
if (int ret = drmModeSetCrtc(backend->gpu->fd, connector->crtc->id, 0, 0, 0, nullptr, 0, nullptr); ret) {
|
||||
connector->backend->backend->log(AQ_LOG_ERROR, std::format("legacy drm: reset failed: {}", strerror(-ret)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
Loading…
Reference in a new issue