diff --git a/include/aquamarine/backend/DRM.hpp b/include/aquamarine/backend/DRM.hpp index ab62e89..7c2ddaa 100644 --- a/include/aquamarine/backend/DRM.hpp +++ b/include/aquamarine/backend/DRM.hpp @@ -179,6 +179,8 @@ 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 @@ -186,7 +188,7 @@ namespace Aquamarine { uint32_t mode_id; uint32_t out_fence_ptr; }; - uint32_t props[7] = {0}; + uint32_t props[9] = {0}; }; UDRMCRTCProps props; }; @@ -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 getRenderFormats(); int getConnectorID(); @@ -247,15 +250,20 @@ namespace Aquamarine { bool test = false; drmModeModeInfo modeInfo; std::optional ctm; + std::optional hdrMetadata; struct { - uint32_t gammaLut = 0; - uint32_t fbDamage = 0; - uint32_t modeBlob = 0; - uint32_t ctmBlob = 0; - bool blobbed = false; - bool gammad = false; - bool ctmd = 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 connector); @@ -269,7 +277,7 @@ namespace Aquamarine { void disconnect(); Hyprutils::Memory::CSharedPointer getCurrentCRTC(const drmModeConnector* connector); drmModeModeInfo* getCurrentMode(); - void parseEDID(std::vector data); + IOutput::SParsedEDID parseEDID(std::vector data); bool commitState(SDRMConnectorCommitData& data); void applyCommit(const SDRMConnectorCommitData& data); void rollbackCommit(const SDRMConnectorCommitData& data); @@ -315,17 +323,29 @@ namespace Aquamarine { uint32_t vrr_capable; // not guaranteed to exist uint32_t subconnector; // not guaranteed to exist uint32_t non_desktop; - uint32_t panel_orientation; // not guaranteed to exist - uint32_t content_type; // not guaranteed to exist - uint32_t max_bpc; // not guaranteed to exist + uint32_t panel_orientation; // not guaranteed to exist + uint32_t content_type; // not guaranteed to exist + uint32_t max_bpc; // not guaranteed to exist + uint32_t Colorspace; // not guaranteed to exist + uint32_t hdr_output_metadata; // not guaranteed to exist // atomic-modesetting only uint32_t crtc_id; }; - uint32_t props[4] = {0}; + uint32_t props[13] = {0}; }; UDRMConnectorProps props; + + union UDRMConnectorColorspace { + struct { + uint32_t Default; + uint32_t BT2020_RGB; + uint32_t BT2020_YCC; + }; + uint32_t props[3] = {0}; + }; + UDRMConnectorColorspace colorspace; }; class IDRMImplementation { diff --git a/include/aquamarine/output/Output.hpp b/include/aquamarine/output/Output.hpp index 1288a1f..5775753 100644 --- a/include/aquamarine/output/Output.hpp +++ b/include/aquamarine/output/Output.hpp @@ -53,6 +53,8 @@ namespace Aquamarine { AQ_OUTPUT_STATE_EXPLICIT_IN_FENCE = (1 << 8), 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 { @@ -62,7 +64,8 @@ namespace Aquamarine { bool enabled = false; bool adaptiveSync = false; eOutputPresentationMode presentationMode = AQ_OUTPUT_PRESENTATION_VSYNC; - std::vector gammaLut; // Gamma lut in the format [r,g,b]+ + std::vector gammaLut; // Gamma lut in the format [r,g,b]+ + std::vector degammaLut; // Gamma lut in the format [r,g,b]+ Hyprutils::Math::Vector2D lastModeSize; Hyprutils::Memory::CWeakPointer mode; Hyprutils::Memory::CSharedPointer customMode; @@ -70,6 +73,8 @@ namespace Aquamarine { Hyprutils::Memory::CSharedPointer buffer; int32_t explicitInFence = -1, explicitOutFence = -1; Hyprutils::Math::Mat3x3 ctm; + bool wideColorGamut = false; + hdr_output_metadata hdrMetadata; }; const SInternalState& state(); @@ -80,6 +85,7 @@ namespace Aquamarine { void setAdaptiveSync(bool enabled); void setPresentationMode(eOutputPresentationMode mode); void setGammaLut(const std::vector& lut); + void setDeGammaLut(const std::vector& lut); void setMode(Hyprutils::Memory::CSharedPointer mode); void setCustomMode(Hyprutils::Memory::CSharedPointer mode); void setFormat(uint32_t drmFormat); @@ -88,6 +94,8 @@ namespace Aquamarine { void enableExplicitOutFenceForNextCommit(); void resetExplicitFences(); void setCTM(const Hyprutils::Math::Mat3x3& ctm); + void setWideColorGamut(bool wcg); + void setHDRMetadata(const hdr_output_metadata& metadata); private: SInternalState internalState; @@ -119,6 +127,32 @@ namespace Aquamarine { AQ_SCHEDULE_ANIMATION_DAMAGE, }; + struct SHDRMetadata { + float desiredContentMaxLuminance = 0; + float desiredMaxFrameAverageLuminance = 0; + float desiredContentMinLuminance = 0; + bool supportsPQ = false; + }; + + struct xy { + double x = 0; + double y = 0; + }; + + struct SChromaticityCoords { + xy red; + xy green; + xy blue; + xy white; + }; + + struct SParsedEDID { + std::string make, serial, model; + std::optional hdrMetadata; + std::optional chromaticityCoords; + bool supportsBT2020 = false; + }; + virtual bool commit() = 0; virtual bool test() = 0; virtual Hyprutils::Memory::CSharedPointer getBackend() = 0; @@ -130,9 +164,11 @@ 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; + SParsedEDID parsedEDID; Hyprutils::Math::Vector2D physicalSize; bool enabled = false; bool nonDesktop = false; diff --git a/src/backend/drm/DRM.cpp b/src/backend/drm/DRM.cpp index 22d905a..cc44501 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include #include @@ -19,6 +21,7 @@ extern "C" { #include #include #include +#include #include #include #include @@ -1101,6 +1104,8 @@ bool Aquamarine::SDRMConnector::init(drmModeConnector* connector) { if (!getDRMConnectorProps(backend->gpu->fd, id, &props)) return false; + if (props.Colorspace) + getDRMConnectorColorspace(backend->gpu->fd, props.Colorspace, &colorspace); auto name = drmModeGetConnectorTypeName(connector->connector_type); if (!name) @@ -1166,11 +1171,12 @@ drmModeModeInfo* Aquamarine::SDRMConnector::getCurrentMode() { return modeInfo; } -void Aquamarine::SDRMConnector::parseEDID(std::vector data) { - auto info = di_info_parse_edid(data.data(), data.size()); +IOutput::SParsedEDID Aquamarine::SDRMConnector::parseEDID(std::vector data) { + auto info = di_info_parse_edid(data.data(), data.size()); + IOutput::SParsedEDID parsed = {}; if (!info) { backend->backend->log(AQ_LOG_ERROR, "drm: failed to parse edid"); - return; + return parsed; } auto edid = di_info_get_edid(info); @@ -1187,7 +1193,64 @@ void Aquamarine::SDRMConnector::parseEDID(std::vector data) { model = mod ? mod : ""; serial = ser ? ser : ""; + parsed.make = make; + parsed.model = model; + parsed.serial = serial; + + const auto chromaticity = di_edid_get_chromaticity_coords(edid); + if (chromaticity) { + parsed.chromaticityCoords = IOutput::SChromaticityCoords{ + IOutput::xy{chromaticity->red_x, chromaticity->red_y}, + IOutput::xy{chromaticity->green_x, chromaticity->green_y}, + IOutput::xy{chromaticity->blue_x, chromaticity->blue_y}, + IOutput::xy{chromaticity->white_x, chromaticity->white_y}, + }; + TRACE(backend->backend->log(AQ_LOG_TRACE, + std::format("EDID: chromaticity coords {},{} {},{} {},{} {},{}", parsed.chromaticityCoords->red.x, parsed.chromaticityCoords->red.y, + parsed.chromaticityCoords->green.x, parsed.chromaticityCoords->green.y, parsed.chromaticityCoords->blue.x, + parsed.chromaticityCoords->blue.y, parsed.chromaticityCoords->white.y, parsed.chromaticityCoords->white.y))); + } + + auto exts = di_edid_get_extensions(edid); + + for (; *exts != nullptr; exts++) { + auto tag = di_edid_ext_get_tag(*exts); + TRACE(backend->backend->log(AQ_LOG_TRACE, std::format("EDID: checking ext {}", (uint32_t)tag))); + if (tag == DI_EDID_EXT_DISPLAYID) + backend->backend->log(AQ_LOG_WARNING, "FIXME: support displayid blocks"); + + const auto cta = di_edid_ext_get_cta(*exts); + if (cta) { + TRACE(backend->backend->log(AQ_LOG_TRACE, "EDID: found CTA")); + const di_cta_hdr_static_metadata_block* hdr_static_metadata = nullptr; + const di_cta_colorimetry_block* colorimetry = nullptr; + auto blocks = di_edid_cta_get_data_blocks(cta); + for (; *blocks != nullptr; blocks++) { + if (!hdr_static_metadata && (hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(*blocks))) { + TRACE(backend->backend->log(AQ_LOG_TRACE, std::format("EDID: found HDR {}", hdr_static_metadata->eotfs->pq))); + parsed.hdrMetadata = IOutput::SHDRMetadata{ + .desiredContentMaxLuminance = hdr_static_metadata->desired_content_max_luminance, + .desiredMaxFrameAverageLuminance = hdr_static_metadata->desired_content_max_frame_avg_luminance, + .desiredContentMinLuminance = hdr_static_metadata->desired_content_min_luminance, + .supportsPQ = hdr_static_metadata->eotfs->pq, + }; + continue; + } + if (!colorimetry && (colorimetry = di_cta_data_block_get_colorimetry(*blocks))) { + TRACE(backend->backend->log(AQ_LOG_TRACE, std::format("EDID: found colorimetry {}", colorimetry->bt2020_rgb))); + parsed.supportsBT2020 = colorimetry->bt2020_rgb; + continue; + } + } + break; + } + } + di_info_destroy(info); + + TRACE(backend->backend->log(AQ_LOG_TRACE, "EDID: parsed")); + + return parsed; } void Aquamarine::SDRMConnector::recheckCRTCProps() { @@ -1207,6 +1270,11 @@ void Aquamarine::SDRMConnector::recheckCRTCProps() { backend->backend->log(AQ_LOG_DEBUG, std::format("drm: Explicit sync {}", output->supportsExplicit ? "supported" : "unsupported")); backend->backend->log(AQ_LOG_DEBUG, std::format("drm: connector {} crtc {} CTM", szName, (crtc->props.ctm ? "supports" : "doesn't support"))); + + backend->backend->log(AQ_LOG_DEBUG, + std::format("drm: connector {} crtc {} HDR ({})", szName, (props.hdr_output_metadata ? "supports" : "doesn't support"), props.hdr_output_metadata)); + + backend->backend->log(AQ_LOG_DEBUG, std::format("drm: connector {} crtc {} Colorspace ({})", szName, (props.Colorspace ? "supports" : "doesn't support"), props.Colorspace)); } void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) { @@ -1289,16 +1357,17 @@ void Aquamarine::SDRMConnector::connect(drmModeConnector* connector) { uint8_t* edidData = (uint8_t*)getDRMPropBlob(backend->gpu->fd, id, props.edid, &edidLen); std::vector edid{edidData, edidData + edidLen}; - parseEDID(edid); + auto parsedEDID = parseEDID(edid); free(edidData); edid = {}; // TODO: subconnectors - output->make = make; - output->model = model; - output->serial = serial; + output->make = parsedEDID.make; + output->model = parsedEDID.model; + output->serial = parsedEDID.serial; + output->parsedEDID = parsedEDID; output->description = std::format("{} {} {} ({})", make, model, serial, szName); output->needsFrame = true; @@ -1609,6 +1678,9 @@ bool Aquamarine::CDRMOutput::commitState(bool onlyTest) { if (COMMITTED & COutputState::eOutputStateProperties::AQ_OUTPUT_STATE_CTM) data.ctm = STATE.ctm; + if (COMMITTED & COutputState::eOutputStateProperties::AQ_OUTPUT_STATE_HDR) + data.hdrMetadata = STATE.hdrMetadata; + data.blocking = BLOCKING || formatMismatch; data.modeset = NEEDS_RECONFIG || lastCommitNoBuffer || formatMismatch; data.flags = flags; @@ -1787,6 +1859,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 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"); diff --git a/src/backend/drm/Props.cpp b/src/backend/drm/Props.cpp index 3f8128b..961e665 100644 --- a/src/backend/drm/Props.cpp +++ b/src/backend/drm/Props.cpp @@ -21,8 +21,10 @@ struct prop_info { static const struct prop_info connector_info[] = { #define INDEX(name) (offsetof(SDRMConnector::UDRMConnectorProps, name) / sizeof(uint32_t)) {"CRTC_ID", INDEX(crtc_id)}, + {"Colorspace", INDEX(Colorspace)}, {"DPMS", INDEX(dpms)}, {"EDID", INDEX(edid)}, + {"HDR_OUTPUT_METADATA", INDEX(hdr_output_metadata)}, {"PATH", INDEX(path)}, {"content type", INDEX(content_type)}, {"link-status", INDEX(link_status)}, @@ -34,9 +36,18 @@ static const struct prop_info connector_info[] = { #undef INDEX }; +static const struct prop_info colorspace_info[] = { +#define INDEX(name) (offsetof(SDRMConnector::UDRMConnectorColorspace, name) / sizeof(uint32_t)) + {"BT2020_RGB", INDEX(BT2020_RGB)}, + {"BT2020_YCC", INDEX(BT2020_YCC)}, + {"Default", INDEX(Default)}, +#undef INDEX +}; + 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)}, @@ -95,10 +106,30 @@ namespace Aquamarine { return true; } + static bool scanPropertyEnum(int fd, uint32_t propertyId, uint32_t* result, const prop_info* info, size_t info_len) { + drmModePropertyRes* prop = drmModeGetProperty(fd, propertyId); + if (!prop) + return false; + + for (uint32_t i = 0; i < prop->count_enums; ++i) { + const prop_info* p = (prop_info*)bsearch(prop->enums[i].name, info, info_len, sizeof(info[0]), comparePropInfo); + if (p) + result[p->index] = prop->enums[i].value; + } + + drmModeFreeProperty(prop); + + return true; + } + bool getDRMConnectorProps(int fd, uint32_t id, SDRMConnector::UDRMConnectorProps* out) { return scanProperties(fd, id, DRM_MODE_OBJECT_CONNECTOR, out->props, connector_info, sizeof(connector_info) / sizeof(connector_info[0])); } + bool getDRMConnectorColorspace(int fd, uint32_t id, SDRMConnector::UDRMConnectorColorspace* out) { + return scanPropertyEnum(fd, id, out->props, colorspace_info, sizeof(colorspace_info) / sizeof(colorspace_info[0])); + } + bool getDRMCRTCProps(int fd, uint32_t id, SDRMCRTC::UDRMCRTCProps* out) { return scanProperties(fd, id, DRM_MODE_OBJECT_CRTC, out->props, crtc_info, sizeof(crtc_info) / sizeof(crtc_info[0])); } diff --git a/src/backend/drm/Props.hpp b/src/backend/drm/Props.hpp index 24a7806..371ff60 100644 --- a/src/backend/drm/Props.hpp +++ b/src/backend/drm/Props.hpp @@ -4,6 +4,7 @@ namespace Aquamarine { bool getDRMConnectorProps(int fd, uint32_t id, SDRMConnector::UDRMConnectorProps* out); + bool getDRMConnectorColorspace(int fd, uint32_t id, SDRMConnector::UDRMConnectorColorspace* out); bool getDRMCRTCProps(int fd, uint32_t id, SDRMCRTC::UDRMCRTCProps* out); bool getDRMPlaneProps(int fd, uint32_t id, SDRMPlane::UDRMPlaneProps* out); bool getDRMProp(int fd, uint32_t obj, uint32_t prop, uint64_t* ret); diff --git a/src/backend/drm/impl/Atomic.cpp b/src/backend/drm/impl/Atomic.cpp index 10d517c..285bba5 100644 --- a/src/backend/drm/impl/Atomic.cpp +++ b/src/backend/drm/impl/Atomic.cpp @@ -1,5 +1,7 @@ #include +#include #include +#include #include #include #include @@ -103,12 +105,21 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint add(connector->crtc->id, connector->crtc->props.active, enable); if (enable) { + if (connector->props.Colorspace && connector->colorspace.BT2020_RGB) + add(connector->id, connector->props.Colorspace, STATE.wideColorGamut ? connector->colorspace.BT2020_RGB : connector->colorspace.Default); + + if (connector->props.hdr_output_metadata) + add(connector->id, connector->props.hdr_output_metadata, data.atomic.hdrd ? data.atomic.hdrBlob : 0); + if (connector->output->supportsExplicit && STATE.committed & COutputState::AQ_OUTPUT_STATE_EXPLICIT_OUT_FENCE) add(connector->crtc->id, connector->crtc->props.out_fence_ptr, (uintptr_t)&STATE.explicitOutFence); 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); @@ -246,30 +257,38 @@ 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. + auto prepareGammaBlob = [connector](uint32_t prop, const std::vector& 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 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()) { if (!connector->crtc->props.ctm) @@ -295,6 +314,32 @@ bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPoin } } + if ((STATE.committed & COutputState::AQ_OUTPUT_STATE_HDR) && data.hdrMetadata.has_value()) { + if (!connector->props.hdr_output_metadata) + connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to commit hdr metadata: no HDR_OUTPUT_METADATA prop support"); + else { + if (!data.hdrMetadata->hdmi_metadata_type1.eotf) { + data.atomic.hdrBlob = 0; + data.atomic.hdrd = false; + } else if (drmModeCreatePropertyBlob(connector->backend->gpu->fd, &data.hdrMetadata.value(), sizeof(hdr_output_metadata), &data.atomic.hdrBlob)) { + connector->backend->backend->log(AQ_LOG_ERROR, "atomic drm: failed to create a hdr metadata blob"); + data.atomic.hdrBlob = 0; + } else { + data.atomic.hdrd = true; + TRACE(connector->backend->backend->log( + AQ_LOG_TRACE, + std::format("atomic drm: setting hdr min {}, max {}, avg {}, content {}, primaries {},{} {},{} {},{} {},{}", + data.hdrMetadata->hdmi_metadata_type1.min_display_mastering_luminance, data.hdrMetadata->hdmi_metadata_type1.max_display_mastering_luminance, + data.hdrMetadata->hdmi_metadata_type1.max_fall, data.hdrMetadata->hdmi_metadata_type1.max_cll, + data.hdrMetadata->hdmi_metadata_type1.display_primaries[0].x, data.hdrMetadata->hdmi_metadata_type1.display_primaries[0].y, + data.hdrMetadata->hdmi_metadata_type1.display_primaries[1].x, data.hdrMetadata->hdmi_metadata_type1.display_primaries[1].y, + data.hdrMetadata->hdmi_metadata_type1.display_primaries[2].x, data.hdrMetadata->hdmi_metadata_type1.display_primaries[2].y, + data.hdrMetadata->hdmi_metadata_type1.display_primaries[0].x, data.hdrMetadata->hdmi_metadata_type1.white_point.x, + data.hdrMetadata->hdmi_metadata_type1.white_point.y))); + } + } + } + if ((STATE.committed & COutputState::AQ_OUTPUT_STATE_DAMAGE) && connector->crtc->primary->props.fb_damage_clips && MODE) { if (STATE.damage.empty()) data.atomic.fbDamage = 0; diff --git a/src/output/Output.cpp b/src/output/Output.cpp index 6186eb1..5be02d2 100644 --- a/src/output/Output.cpp +++ b/src/output/Output.cpp @@ -39,6 +39,10 @@ size_t Aquamarine::IOutput::getGammaSize() { return 0; } +size_t Aquamarine::IOutput::getDeGammaSize() { + return 0; +} + bool Aquamarine::IOutput::destroy() { return false; } @@ -77,6 +81,11 @@ void Aquamarine::COutputState::setGammaLut(const std::vector& lut) { internalState.committed |= AQ_OUTPUT_STATE_GAMMA_LUT; } +void Aquamarine::COutputState::setDeGammaLut(const std::vector& lut) { + internalState.gammaLut = lut; + internalState.committed |= AQ_OUTPUT_STATE_DEGAMMA_LUT; +} + void Aquamarine::COutputState::setMode(Hyprutils::Memory::CSharedPointer mode) { internalState.mode = mode; internalState.customMode = nullptr; @@ -119,6 +128,15 @@ void Aquamarine::COutputState::setCTM(const Hyprutils::Math::Mat3x3& ctm) { internalState.committed |= AQ_OUTPUT_STATE_CTM; } +void Aquamarine::COutputState::setWideColorGamut(bool wcg) { + internalState.wideColorGamut = wcg; +} + +void Aquamarine::COutputState::setHDRMetadata(const hdr_output_metadata& metadata) { + internalState.hdrMetadata = metadata; + internalState.committed |= AQ_OUTPUT_STATE_HDR; +} + void Aquamarine::COutputState::onCommit() { internalState.committed = 0; internalState.damage.clear();