mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-17 07:15:59 +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 {
|
class IDRMImplementation {
|
||||||
public:
|
public:
|
||||||
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data) = 0;
|
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 {
|
class CDRMBackend : public IBackendImplementation {
|
||||||
|
@ -259,6 +260,7 @@ namespace Aquamarine {
|
||||||
bool initResources();
|
bool initResources();
|
||||||
bool grabFormats();
|
bool grabFormats();
|
||||||
void scanConnectors();
|
void scanConnectors();
|
||||||
|
void restoreAfterVT();
|
||||||
|
|
||||||
Hyprutils::Memory::CSharedPointer<CSessionDevice> gpu;
|
Hyprutils::Memory::CSharedPointer<CSessionDevice> gpu;
|
||||||
Hyprutils::Memory::CSharedPointer<IDRMImplementation> impl;
|
Hyprutils::Memory::CSharedPointer<IDRMImplementation> impl;
|
||||||
|
@ -277,6 +279,10 @@ namespace Aquamarine {
|
||||||
bool supportsAddFb2Modifiers = false;
|
bool supportsAddFb2Modifiers = false;
|
||||||
} drmProps;
|
} drmProps;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
Hyprutils::Signal::CHyprSignalListener sessionActivate;
|
||||||
|
} listeners;
|
||||||
|
|
||||||
friend class CBackend;
|
friend class CBackend;
|
||||||
friend class CDRMFB;
|
friend class CDRMFB;
|
||||||
friend class CDRMFBAttachment;
|
friend class CDRMFBAttachment;
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace Aquamarine {
|
||||||
public:
|
public:
|
||||||
CDRMLegacyImpl(Hyprutils::Memory::CSharedPointer<CDRMBackend> backend_);
|
CDRMLegacyImpl(Hyprutils::Memory::CSharedPointer<CDRMBackend> backend_);
|
||||||
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data);
|
virtual bool commit(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector, const SDRMConnectorCommitData& data);
|
||||||
|
virtual bool reset(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Aquamarine {
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
bool adaptiveSync = false;
|
bool adaptiveSync = false;
|
||||||
eOutputPresentationMode presentationMode = AQ_OUTPUT_PRESENTATION_VSYNC;
|
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::Math::Vector2D lastModeSize;
|
||||||
Hyprutils::Memory::CWeakPointer<SOutputMode> mode;
|
Hyprutils::Memory::CWeakPointer<SOutputMode> mode;
|
||||||
Hyprutils::Memory::CSharedPointer<SOutputMode> customMode;
|
Hyprutils::Memory::CSharedPointer<SOutputMode> customMode;
|
||||||
|
@ -109,7 +109,7 @@ namespace Aquamarine {
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
bool nonDesktop = false;
|
bool nonDesktop = false;
|
||||||
eSubpixelMode subpixel = AQ_SUBPIXEL_NONE;
|
eSubpixelMode subpixel = AQ_SUBPIXEL_NONE;
|
||||||
bool vrrCapable = false;
|
bool vrrCapable = false, vrrActive = false;
|
||||||
bool needsFrame = false;
|
bool needsFrame = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -23,7 +23,12 @@ using namespace Hyprutils::Math;
|
||||||
#define SP CSharedPointer
|
#define SP CSharedPointer
|
||||||
|
|
||||||
Aquamarine::CDRMBackend::CDRMBackend(SP<CBackend> backend_) : backend(backend_) {
|
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) {
|
static udev_enumerate* enumDRMCards(udev* udev) {
|
||||||
|
@ -206,6 +211,45 @@ bool Aquamarine::CDRMBackend::sessionActive() {
|
||||||
return backend->session->active;
|
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() {
|
bool Aquamarine::CDRMBackend::checkFeatures() {
|
||||||
uint64_t curW = 0, curH = 0;
|
uint64_t curW = 0, curH = 0;
|
||||||
if (drmGetCap(gpu->fd, DRM_CAP_CURSOR_WIDTH, &curW))
|
if (drmGetCap(gpu->fd, DRM_CAP_CURSOR_WIDTH, &curW))
|
||||||
|
|
|
@ -41,7 +41,6 @@ bool Aquamarine::CDRMLegacyImpl::commitInternal(Hyprutils::Memory::CSharedPointe
|
||||||
mode = (drmModeModeInfo*)&data.modeInfo;
|
mode = (drmModeModeInfo*)&data.modeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
connector->backend->backend->log(AQ_LOG_DEBUG, std::format("legacy drm: Modesetting CRTC, connectors: {}", connectors.size()));
|
|
||||||
connector->backend->backend->log(
|
connector->backend->backend->log(
|
||||||
AQ_LOG_DEBUG,
|
AQ_LOG_DEBUG,
|
||||||
std::format("legacy drm: Modesetting CRTC, mode: clock {} hdisplay {} vdisplay {} vrefresh {}", mode->clock, mode->hdisplay, mode->vdisplay, mode->vrefresh));
|
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
|
// TODO: cursor plane
|
||||||
if (drmModeSetCursor(connector->backend->gpu->fd, connector->crtc->id, 0, 0, 0))
|
if (drmModeSetCursor(connector->backend->gpu->fd, connector->crtc->id, 0, 0, 0))
|
||||||
|
@ -86,3 +101,15 @@ bool Aquamarine::CDRMLegacyImpl::commit(Hyprutils::Memory::CSharedPointer<SDRMCo
|
||||||
|
|
||||||
return commitInternal(connector, data);
|
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