Skip to content

Commit 7e4ae2e

Browse files
committed
drm/atomic: add support for gamma ramps
1 parent 0eb28d4 commit 7e4ae2e

File tree

3 files changed

+48
-9
lines changed

3 files changed

+48
-9
lines changed

include/aquamarine/backend/DRM.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ namespace Aquamarine {
162162
virtual void scheduleFrame();
163163
virtual void setCursorVisible(bool visible);
164164
virtual Hyprutils::Math::Vector2D cursorPlaneSize();
165+
virtual size_t getGammaSize();
165166

166167
Hyprutils::Memory::CWeakPointer<CDRMOutput> self;
167168
bool cursorVisible = true;
@@ -199,6 +200,7 @@ namespace Aquamarine {
199200
uint32_t fbDamage = 0;
200201
uint32_t modeBlob = 0;
201202
bool blobbed = false;
203+
bool gammad = false;
202204
} atomic;
203205

204206
void calculateMode(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
@@ -321,6 +323,8 @@ namespace Aquamarine {
321323
std::vector<Hyprutils::Memory::CSharedPointer<SDRMConnector>> connectors;
322324
std::vector<SDRMFormat> formats;
323325

326+
bool atomic = false;
327+
324328
struct {
325329
Hyprutils::Math::Vector2D cursorSize;
326330
bool supportsAsyncCommit = false;

src/backend/drm/DRM.cpp

+18-3
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,8 @@ bool Aquamarine::CDRMBackend::checkFeatures() {
315315
drmProps.supportsAsyncCommit = drmGetCap(gpu->fd, DRM_CAP_ASYNC_PAGE_FLIP, &cap) == 0 && cap == 1;
316316
drmProps.supportsAddFb2Modifiers = drmGetCap(gpu->fd, DRM_CAP_ADDFB2_MODIFIERS, &cap) == 0 && cap == 1;
317317

318-
// FIXME: move to NO_ATOMIC when this piece of shit works
319-
if (!envEnabled("AQ_ATOMIC")) {
320-
backend->log(AQ_LOG_WARNING, "drm: AQ_ATOMIC not enabled, using the legacy drm iface");
318+
if (envEnabled("AQ_NO_ATOMIC")) {
319+
backend->log(AQ_LOG_WARNING, "drm: AQ_NO_ATOMIC enabled, using the legacy drm iface");
321320
impl = makeShared<CDRMLegacyImpl>(self.lock());
322321
} else if (drmSetClientCap(gpu->fd, DRM_CLIENT_CAP_ATOMIC, 1)) {
323322
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() {
326325
backend->log(AQ_LOG_DEBUG, "drm: Atomic supported, using atomic for modesetting");
327326
impl = makeShared<CDRMAtomicImpl>(self.lock());
328327
drmProps.supportsAsyncCommit = drmGetCap(gpu->fd, DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP, &cap) == 0 && cap == 1;
328+
atomic = true;
329329
}
330330

331331
backend->log(AQ_LOG_DEBUG, std::format("drm: drmProps.supportsAsyncCommit: {}", drmProps.supportsAsyncCommit));
@@ -1206,6 +1206,21 @@ Vector2D Aquamarine::CDRMOutput::cursorPlaneSize() {
12061206
return backend->drmProps.cursorSize;
12071207
}
12081208

1209+
size_t Aquamarine::CDRMOutput::getGammaSize() {
1210+
if (!backend->atomic) {
1211+
backend->log(AQ_LOG_ERROR, "No support for gamma on the legacy iface");
1212+
return 0;
1213+
}
1214+
1215+
uint64_t size = 0;
1216+
if (!getDRMProp(backend->gpu->fd, connector->crtc->id, connector->crtc->props.gamma_lut_size, &size)) {
1217+
backend->log(AQ_LOG_ERROR, "Couldn't get the gamma_size prop");
1218+
return 0;
1219+
}
1220+
1221+
return size;
1222+
}
1223+
12091224
Aquamarine::CDRMOutput::CDRMOutput(const std::string& name_, Hyprutils::Memory::CWeakPointer<CDRMBackend> backend_, SP<SDRMConnector> connector_) :
12101225
backend(backend_), connector(connector_) {
12111226
name = name_;

src/backend/drm/impl/Atomic.cpp

+26-6
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
9999
add(connector->crtc->id, connector->crtc->props.active, enable);
100100

101101
if (enable) {
102-
// TODO: gamma
102+
if (connector->crtc->props.gamma_lut && data.atomic.gammad)
103+
add(connector->crtc->id, connector->crtc->props.gamma_lut, data.atomic.gammaLut);
104+
103105
if (connector->crtc->props.vrr_enabled)
104106
add(connector->crtc->id, connector->crtc->props.vrr_enabled, (uint64_t)STATE.adaptiveSync);
105107

@@ -184,8 +186,7 @@ void Aquamarine::CDRMAtomicRequest::rollback(SDRMConnectorCommitData& data) {
184186
conn->crtc->atomic.ownModeID = true;
185187
if (data.atomic.blobbed)
186188
rollbackBlob(&conn->crtc->atomic.modeID, data.atomic.modeBlob);
187-
// TODO: gamma
188-
//rollbackBlob(&conn->crtc->atomic.gammaLut, conn->atomic.gammaLut);
189+
rollbackBlob(&conn->crtc->atomic.gammaLut, data.atomic.gammaLut);
189190
destroyBlob(data.atomic.fbDamage);
190191
}
191192

@@ -199,8 +200,7 @@ void Aquamarine::CDRMAtomicRequest::apply(SDRMConnectorCommitData& data) {
199200
conn->crtc->atomic.ownModeID = true;
200201
if (data.atomic.blobbed)
201202
commitBlob(&conn->crtc->atomic.modeID, data.atomic.modeBlob);
202-
// TODO: gamma
203-
//commitBlob(&conn->crtc->atomic.gammaLut, conn->atomic.gammaLut);
203+
commitBlob(&conn->crtc->atomic.gammaLut, data.atomic.gammaLut);
204204
destroyBlob(data.atomic.fbDamage);
205205
}
206206

@@ -227,7 +227,27 @@ bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPoin
227227
}
228228
}
229229

230-
// TODO: gamma
230+
if (STATE.committed & COutputState::AQ_OUTPUT_STATE_GAMMA_LUT) {
231+
if (!connector->crtc->props.gamma_lut) // TODO: allow this with legacy gamma, perhaps.
232+
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to commit gamma: no gamma_lut prop");
233+
else {
234+
std::vector<drm_color_lut> lut;
235+
lut.resize(STATE.gammaLut.size() / 3); // [r,g,b]+
236+
237+
for (size_t i = 0; i < lut.size(); ++i) {
238+
lut.at(i).red = STATE.gammaLut.at(i * 3 + 0);
239+
lut.at(i).green = STATE.gammaLut.at(i * 3 + 1);
240+
lut.at(i).blue = STATE.gammaLut.at(i * 3 + 2);
241+
lut.at(i).reserved = 0;
242+
}
243+
244+
if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, lut.data(), lut.size() * sizeof(drm_color_lut), &data.atomic.gammaLut)) {
245+
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to create a gamma blob");
246+
data.atomic.gammaLut = 0;
247+
} else
248+
data.atomic.gammad = true;
249+
}
250+
}
231251

232252
if (STATE.committed & COutputState::AQ_OUTPUT_STATE_DAMAGE && connector->crtc->primary->props.fb_damage_clips) {
233253
if (STATE.damage.empty())

0 commit comments

Comments
 (0)