diff --git a/include/aquamarine/backend/DRM.hpp b/include/aquamarine/backend/DRM.hpp index e3e72e7..4058126 100644 --- a/include/aquamarine/backend/DRM.hpp +++ b/include/aquamarine/backend/DRM.hpp @@ -4,7 +4,6 @@ #include "../allocator/Swapchain.hpp" #include "../output/Output.hpp" #include "../input/Input.hpp" -#include #include #include #include @@ -273,7 +272,7 @@ namespace Aquamarine { void disconnect(); Hyprutils::Memory::CSharedPointer getCurrentCRTC(const drmModeConnector* connector); drmModeModeInfo* getCurrentMode(); - IOutput::ParsedEDID parseEDID(std::vector data); + IOutput::SParsedEDID parseEDID(std::vector data); bool commitState(SDRMConnectorCommitData& data); void applyCommit(const SDRMConnectorCommitData& data); void rollbackCommit(const SDRMConnectorCommitData& data); diff --git a/include/aquamarine/output/Output.hpp b/include/aquamarine/output/Output.hpp index 9ba10a1..914f1a7 100644 --- a/include/aquamarine/output/Output.hpp +++ b/include/aquamarine/output/Output.hpp @@ -124,13 +124,11 @@ namespace Aquamarine { AQ_SCHEDULE_ANIMATION_DAMAGE, }; - struct HDRMetadata { - bool supported = false; - double desiredContentMinLuminance; - std::optional desiredContentMaxLuminance; - std::optional desiredMaxFrameAverageLuminance; - bool supportsPQ; - bool supportsBT2020; + struct SHDRMetadata { + float desiredContentMaxLuminance = 0; + float desiredMaxFrameAverageLuminance = 0; + float desiredContentMinLuminance = 0; + bool supportsPQ = false; }; struct xy { @@ -138,17 +136,18 @@ namespace Aquamarine { double y = 0; }; - struct ChromaticityCoords { + struct SChromaticityCoords { xy red; xy green; xy blue; xy white; }; - struct ParsedEDID { - std::string make, serial, model; - std::optional hdrMetadata; - std::optional chromaticityCoords; + struct SParsedEDID { + std::string make, serial, model; + std::optional hdrMetadata; + std::optional chromaticityCoords; + bool supportsBT2020 = false; }; virtual bool commit() = 0; @@ -165,7 +164,7 @@ namespace Aquamarine { virtual bool destroy(); // not all backends allow this!!! std::string name, description, make, model, serial; - ParsedEDID parsedEDID; + 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 c482461..895e1b3 100644 --- a/src/backend/drm/DRM.cpp +++ b/src/backend/drm/DRM.cpp @@ -1150,9 +1150,9 @@ drmModeModeInfo* Aquamarine::SDRMConnector::getCurrentMode() { return modeInfo; } -IOutput::ParsedEDID Aquamarine::SDRMConnector::parseEDID(std::vector data) { - auto info = di_info_parse_edid(data.data(), data.size()); - IOutput::ParsedEDID parsed = {}; +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 parsed; @@ -1176,50 +1176,39 @@ IOutput::ParsedEDID Aquamarine::SDRMConnector::parseEDID(std::vector da parsed.model = model; parsed.serial = serial; - // copied from kwin const auto chromaticity = di_edid_get_chromaticity_coords(edid); if (chromaticity) { - parsed.chromaticityCoords = IOutput::ChromaticityCoords{ + 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}, }; - } else { - parsed.chromaticityCoords.reset(); } - const di_edid_cta* cta = nullptr; - const di_edid_ext* const* exts = di_edid_get_extensions(edid); - const di_cta_hdr_static_metadata_block* hdr_static_metadata = nullptr; - const di_cta_colorimetry_block* colorimetry = nullptr; + + auto exts = di_edid_get_extensions(edid); for (; *exts != nullptr; exts++) { - if (!cta && (cta = di_edid_ext_get_cta(*exts))) { - continue; - } - } - if (cta) { - const di_cta_data_block* const* 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))) { - continue; - } - if (!colorimetry && (colorimetry = di_cta_data_block_get_colorimetry(*blocks))) { - continue; + const auto cta = di_edid_ext_get_cta(*exts); + if (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))) { + 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))) { + parsed.supportsBT2020 = colorimetry->bt2020_rgb; + continue; + } } - } - if (hdr_static_metadata) { - parsed.hdrMetadata = IOutput::HDRMetadata{ - .desiredContentMinLuminance = hdr_static_metadata->desired_content_min_luminance, - .desiredContentMaxLuminance = - hdr_static_metadata->desired_content_max_luminance > 0 ? std::make_optional(hdr_static_metadata->desired_content_max_luminance) : std::nullopt, - .desiredMaxFrameAverageLuminance = hdr_static_metadata->desired_content_max_frame_avg_luminance > 0 ? - std::make_optional(hdr_static_metadata->desired_content_max_frame_avg_luminance) : - std::nullopt, - .supportsPQ = hdr_static_metadata->eotfs->pq, - .supportsBT2020 = colorimetry && colorimetry->bt2020_rgb, - }; - } else { - parsed.hdrMetadata.reset(); + break; } } diff --git a/src/backend/drm/Props.cpp b/src/backend/drm/Props.cpp index 9434e51..ef777d2 100644 --- a/src/backend/drm/Props.cpp +++ b/src/backend/drm/Props.cpp @@ -38,7 +38,9 @@ static const struct prop_info connector_info[] = { 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)} + {"BT2020_RGB", INDEX(BT2020_RGB)}, + {"BT2020_YCC", INDEX(BT2020_YCC)}, + {"Default", INDEX(Default)}, #undef INDEX }; diff --git a/src/backend/drm/impl/Atomic.cpp b/src/backend/drm/impl/Atomic.cpp index 21f1c6d..940c6c8 100644 --- a/src/backend/drm/impl/Atomic.cpp +++ b/src/backend/drm/impl/Atomic.cpp @@ -107,8 +107,8 @@ void Aquamarine::CDRMAtomicRequest::addConnector(Hyprutils::Memory::CSharedPoint 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 && data.atomic.hdrd) - add(connector->id, connector->props.hdr_output_metadata, data.atomic.hdrBlob); + 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); @@ -306,7 +306,10 @@ bool Aquamarine::CDRMAtomicImpl::prepareConnector(Hyprutils::Memory::CSharedPoin 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 (drmModeCreatePropertyBlob(connector->backend->gpu->fd, &data.hdrMetadata.value(), sizeof(hdr_output_metadata), &data.atomic.hdrBlob)) { + 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