drm/atomic: add support for gamma ramps

This commit is contained in:
Vaxry 2024-07-02 12:41:32 +02:00
parent 0eb28d40f0
commit 7e4ae2e226
3 changed files with 48 additions and 9 deletions

View file

@ -162,6 +162,7 @@ namespace Aquamarine {
virtual void scheduleFrame();
virtual void setCursorVisible(bool visible);
virtual Hyprutils::Math::Vector2D cursorPlaneSize();
virtual size_t getGammaSize();
Hyprutils::Memory::CWeakPointer<CDRMOutput> self;
bool cursorVisible = true;
@ -199,6 +200,7 @@ namespace Aquamarine {
uint32_t fbDamage = 0;
uint32_t modeBlob = 0;
bool blobbed = false;
bool gammad = false;
} atomic;
void calculateMode(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
@ -321,6 +323,8 @@ namespace Aquamarine {
std::vector<Hyprutils::Memory::CSharedPointer<SDRMConnector>> connectors;
std::vector<SDRMFormat> formats;
bool atomic = false;
struct {
Hyprutils::Math::Vector2D cursorSize;
bool supportsAsyncCommit = false;

View file

@ -315,9 +315,8 @@ bool Aquamarine::CDRMBackend::checkFeatures() {
drmProps.supportsAsyncCommit = drmGetCap(gpu->fd, DRM_CAP_ASYNC_PAGE_FLIP, &cap) == 0 && cap == 1;
drmProps.supportsAddFb2Modifiers = drmGetCap(gpu->fd, DRM_CAP_ADDFB2_MODIFIERS, &cap) == 0 && cap == 1;
// FIXME: move to NO_ATOMIC when this piece of shit works
if (!envEnabled("AQ_ATOMIC")) {
backend->log(AQ_LOG_WARNING, "drm: AQ_ATOMIC not enabled, using the legacy drm iface");
if (envEnabled("AQ_NO_ATOMIC")) {
backend->log(AQ_LOG_WARNING, "drm: AQ_NO_ATOMIC enabled, using the legacy drm iface");
impl = makeShared<CDRMLegacyImpl>(self.lock());
} else if (drmSetClientCap(gpu->fd, DRM_CLIENT_CAP_ATOMIC, 1)) {
backend->log(AQ_LOG_WARNING, "drm: failed to set DRM_CLIENT_CAP_ATOMIC, falling back to legacy");
@ -326,6 +325,7 @@ bool Aquamarine::CDRMBackend::checkFeatures() {
backend->log(AQ_LOG_DEBUG, "drm: Atomic supported, using atomic for modesetting");
impl = makeShared<CDRMAtomicImpl>(self.lock());
drmProps.supportsAsyncCommit = drmGetCap(gpu->fd, DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP, &cap) == 0 && cap == 1;
atomic = true;
}
backend->log(AQ_LOG_DEBUG, std::format("drm: drmProps.supportsAsyncCommit: {}", drmProps.supportsAsyncCommit));
@ -1206,6 +1206,21 @@ Vector2D Aquamarine::CDRMOutput::cursorPlaneSize() {
return backend->drmProps.cursorSize;
}
size_t Aquamarine::CDRMOutput::getGammaSize() {
if (!backend->atomic) {
backend->log(AQ_LOG_ERROR, "No support for gamma on the legacy iface");
return 0;
}
uint64_t size = 0;
if (!getDRMProp(backend->gpu->fd, connector->crtc->id, connector->crtc->props.gamma_lut_size, &size)) {
backend->log(AQ_LOG_ERROR, "Couldn't get the gamma_size prop");
return 0;
}
return size;
}
Aquamarine::CDRMOutput::CDRMOutput(const std::string& name_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_, SP<SDRMConnector> connector_) :
backend(backend_), connector(connector_) {
name = name_;

View file

@ -99,7 +99,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
add(connector->crtc->id, connector->crtc->props.active, enable);
if (enable) {
// TODO: gamma
if (connector->crtc->props.gamma_lut && data.atomic.gammad)
add(connector->crtc->id, connector->crtc->props.gamma_lut, data.atomic.gammaLut);
if (connector->crtc->props.vrr_enabled)
add(connector->crtc->id, connector->crtc->props.vrr_enabled, (uint64_t)STATE.adaptiveSync);
@ -184,8 +186,7 @@ void Aquamarine::CDRMAtomicRequest::rollback(SDRMConnectorCommitData& data) {
conn->crtc->atomic.ownModeID = true;
if (data.atomic.blobbed)
rollbackBlob(&conn->crtc->atomic.modeID, data.atomic.modeBlob);
// TODO: gamma
//rollbackBlob(&conn->crtc->atomic.gammaLut, conn->atomic.gammaLut);
rollbackBlob(&conn->crtc->atomic.gammaLut, data.atomic.gammaLut);
destroyBlob(data.atomic.fbDamage);
}
@ -199,8 +200,7 @@ void Aquamarine::CDRMAtomicRequest::apply(SDRMConnectorCommitData& data) {
conn->crtc->atomic.ownModeID = true;
if (data.atomic.blobbed)
commitBlob(&conn->crtc->atomic.modeID, data.atomic.modeBlob);
// TODO: gamma
//commitBlob(&conn->crtc->atomic.gammaLut, conn->atomic.gammaLut);
commitBlob(&conn->crtc->atomic.gammaLut, data.atomic.gammaLut);
destroyBlob(data.atomic.fbDamage);
}
@ -227,7 +227,27 @@ bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPoin
}
}
// TODO: gamma
if (STATE.committed & COutputState::AQ_OUTPUT_STATE_GAMMA_LUT) {
if (!connector->crtc->props.gamma_lut) // TODO: allow this with legacy gamma, perhaps.
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to commit gamma: no gamma_lut prop");
else {
std::vector<drm_color_lut> lut;
lut.resize(STATE.gammaLut.size() / 3); // [r,g,b]+
for (size_t i = 0; i < lut.size(); ++i) {
lut.at(i).red = STATE.gammaLut.at(i * 3 + 0);
lut.at(i).green = STATE.gammaLut.at(i * 3 + 1);
lut.at(i).blue = STATE.gammaLut.at(i * 3 + 2);
lut.at(i).reserved = 0;
}
if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, lut.data(), lut.size() * sizeof(drm_color_lut), &data.atomic.gammaLut)) {
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to create a gamma blob");
data.atomic.gammaLut = 0;
} else
data.atomic.gammad = true;
}
}
if (STATE.committed & COutputState::AQ_OUTPUT_STATE_DAMAGE && connector->crtc->primary->props.fb_damage_clips) {
if (STATE.damage.empty())