mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-16 22:05:58 +01:00
drm/atomic: add support for gamma ramps
This commit is contained in:
parent
0eb28d40f0
commit
7e4ae2e226
3 changed files with 48 additions and 9 deletions
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in a new issue