Skip to content

Commit

Permalink
support DEGAMMA_LUT property
Browse files Browse the repository at this point in the history
  • Loading branch information
UjinT34 committed Jan 2, 2025
1 parent 5fad731 commit f79e899
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 23 deletions.
25 changes: 15 additions & 10 deletions include/aquamarine/backend/DRM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,16 @@ namespace Aquamarine {
uint32_t gamma_lut;
uint32_t gamma_lut_size;
uint32_t ctm;
uint32_t degamma_lut;
uint32_t degamma_lut_size;

// atomic-modesetting only

uint32_t active;
uint32_t mode_id;
uint32_t out_fence_ptr;
};
uint32_t props[7] = {0};
uint32_t props[9] = {0};
};
UDRMCRTCProps props;
};
Expand All @@ -203,6 +205,7 @@ namespace Aquamarine {
virtual void setCursorVisible(bool visible);
virtual Hyprutils::Math::Vector2D cursorPlaneSize();
virtual size_t getGammaSize();
virtual size_t getDeGammaSize();
virtual std::vector<SDRMFormat> getRenderFormats();

int getConnectorID();
Expand Down Expand Up @@ -250,15 +253,17 @@ namespace Aquamarine {
std::optional<hdr_output_metadata> hdrMetadata;

struct {
uint32_t gammaLut = 0;
uint32_t fbDamage = 0;
uint32_t modeBlob = 0;
uint32_t ctmBlob = 0;
uint32_t hdrBlob = 0;
bool blobbed = false;
bool gammad = false;
bool ctmd = false;
bool hdrd = false;
uint32_t gammaLut = 0;
uint32_t degammaLut = 0;
uint32_t fbDamage = 0;
uint32_t modeBlob = 0;
uint32_t ctmBlob = 0;
uint32_t hdrBlob = 0;
bool blobbed = false;
bool gammad = false;
bool degammad = false;
bool ctmd = false;
bool hdrd = false;
} atomic;

void calculateMode(Hyprutils::Memory::CSharedPointer<SDRMConnector> connector);
Expand Down
6 changes: 5 additions & 1 deletion include/aquamarine/output/Output.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ namespace Aquamarine {
AQ_OUTPUT_STATE_EXPLICIT_OUT_FENCE = (1 << 9),
AQ_OUTPUT_STATE_CTM = (1 << 10),
AQ_OUTPUT_STATE_HDR = (1 << 11),
AQ_OUTPUT_STATE_DEGAMMA_LUT = (1 << 12),
};

struct SInternalState {
Expand All @@ -63,7 +64,8 @@ namespace Aquamarine {
bool enabled = false;
bool adaptiveSync = false;
eOutputPresentationMode presentationMode = AQ_OUTPUT_PRESENTATION_VSYNC;
std::vector<uint16_t> gammaLut; // Gamma lut in the format [r,g,b]+
std::vector<uint16_t> gammaLut; // Gamma lut in the format [r,g,b]+
std::vector<uint16_t> degammaLut; // Gamma lut in the format [r,g,b]+
Hyprutils::Math::Vector2D lastModeSize;
Hyprutils::Memory::CWeakPointer<SOutputMode> mode;
Hyprutils::Memory::CSharedPointer<SOutputMode> customMode;
Expand All @@ -83,6 +85,7 @@ namespace Aquamarine {
void setAdaptiveSync(bool enabled);
void setPresentationMode(eOutputPresentationMode mode);
void setGammaLut(const std::vector<uint16_t>& lut);
void setDeGammaLut(const std::vector<uint16_t>& lut);
void setMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode);
void setCustomMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode);
void setFormat(uint32_t drmFormat);
Expand Down Expand Up @@ -161,6 +164,7 @@ namespace Aquamarine {
virtual Hyprutils::Math::Vector2D cursorPlaneSize(); // -1, -1 means no set size, 0, 0 means error
virtual void scheduleFrame(const scheduleFrameReason reason = AQ_SCHEDULE_UNKNOWN);
virtual size_t getGammaSize();
virtual size_t getDeGammaSize();
virtual bool destroy(); // not all backends allow this!!!

std::string name, description, make, model, serial;
Expand Down
15 changes: 15 additions & 0 deletions src/backend/drm/DRM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,21 @@ size_t Aquamarine::CDRMOutput::getGammaSize() {
return size;
}

size_t Aquamarine::CDRMOutput::getDeGammaSize() {
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.degamma_lut_size, &size)) {
backend->log(AQ_LOG_ERROR, "Couldn't get the degamma_size prop");
return 0;
}

return size;
}

std::vector<SDRMFormat> Aquamarine::CDRMOutput::getRenderFormats() {
if (!connector->crtc || !connector->crtc->primary || connector->crtc->primary->formats.empty()) {
backend->log(AQ_LOG_ERROR, "Can't get formats: no crtc");
Expand Down
1 change: 1 addition & 0 deletions src/backend/drm/Props.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ static const struct prop_info colorspace_info[] = {
static const struct prop_info crtc_info[] = {
#define INDEX(name) (offsetof(SDRMCRTC::UDRMCRTCProps, name) / sizeof(uint32_t))
{"ACTIVE", INDEX(active)}, {"CTM", INDEX(ctm)},
{"DEGAMMA_LUT", INDEX(degamma_lut)}, {"DEGAMMA_LUT_SIZE", INDEX(degamma_lut_size)},
{"GAMMA_LUT", INDEX(gamma_lut)}, {"GAMMA_LUT_SIZE", INDEX(gamma_lut_size)},
{"MODE_ID", INDEX(mode_id)}, {"OUT_FENCE_PTR", INDEX(out_fence_ptr)},
{"VRR_ENABLED", INDEX(vrr_enabled)},
Expand Down
38 changes: 26 additions & 12 deletions src/backend/drm/impl/Atomic.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <aquamarine/backend/drm/Atomic.hpp>
#include <cstdint>
#include <cstring>
#include <drm_mode.h>
#include <xf86drm.h>
Expand Down Expand Up @@ -116,6 +117,9 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint
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.degamma_lut && data.atomic.degammad)
add(connector->crtc->id, connector->crtc->props.degamma_lut, data.atomic.degammaLut);

if (connector->crtc->props.ctm && data.atomic.ctmd)
add(connector->crtc->id, connector->crtc->props.ctm, data.atomic.ctmBlob);

Expand Down Expand Up @@ -253,29 +257,39 @@ bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPoin
}
}

if (STATE.committed & COutputState::AQ_OUTPUT_STATE_GAMMA_LUT) {
if (!connector->crtc->props.gamma_lut) // TODO: allow this with legacy gamma, perhaps.
static auto prepareGammaBlob = [connector](uint32_t prop, const std::vector<uint16_t>& gammaLut, uint32_t* blobId) -> bool {
if (!prop) // 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 if (STATE.gammaLut.empty()) {
data.atomic.gammaLut = 0;
data.atomic.gammad = true;
else if (gammaLut.empty()) {
blobId = 0;
return true;
} else {
std::vector<drm_color_lut> lut;
lut.resize(STATE.gammaLut.size() / 3); // [r,g,b]+
lut.resize(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).red = gammaLut.at(i * 3 + 0);
lut.at(i).green = gammaLut.at(i * 3 + 1);
lut.at(i).blue = 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)) {
if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, lut.data(), lut.size() * sizeof(drm_color_lut), blobId)) {
connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to create a gamma blob");
data.atomic.gammaLut = 0;
*blobId = 0;
} else
data.atomic.gammad = true;
return true;
}

return false;
};

if (STATE.committed & COutputState::AQ_OUTPUT_STATE_GAMMA_LUT) {
data.atomic.gammad = prepareGammaBlob(connector->crtc->props.gamma_lut, STATE.gammaLut, &data.atomic.gammaLut);
}

if (STATE.committed & COutputState::AQ_OUTPUT_STATE_DEGAMMA_LUT) {
data.atomic.degammad = prepareGammaBlob(connector->crtc->props.degamma_lut, STATE.degammaLut, &data.atomic.degammaLut);
}

if ((STATE.committed & COutputState::AQ_OUTPUT_STATE_CTM) && data.ctm.has_value()) {
Expand Down
9 changes: 9 additions & 0 deletions src/output/Output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ size_t Aquamarine::IOutput::getGammaSize() {
return 0;
}

size_t Aquamarine::IOutput::getDeGammaSize() {
return 0;
}

bool Aquamarine::IOutput::destroy() {
return false;
}
Expand Down Expand Up @@ -77,6 +81,11 @@ void Aquamarine::COutputState::setGammaLut(const std::vector<uint16_t>& lut) {
internalState.committed |= AQ_OUTPUT_STATE_GAMMA_LUT;
}

void Aquamarine::COutputState::setDeGammaLut(const std::vector<uint16_t>& lut) {
internalState.gammaLut = lut;
internalState.committed |= AQ_OUTPUT_STATE_DEGAMMA_LUT;
}

void Aquamarine::COutputState::setMode(Hyprutils::Memory::CSharedPointer<SOutputMode> mode) {
internalState.mode = mode;
internalState.customMode = nullptr;
Expand Down

0 comments on commit f79e899

Please sign in to comment.