From 6d3b17ee832411f627d8bed6b74e09b4fa55e2fb Mon Sep 17 00:00:00 2001 From: UjinT34 <41110182+UjinT34@users.noreply.github.com> Date: Sat, 27 Dec 2025 20:01:46 +0300 Subject: render/cm: various updates, remove old protocols (#12693) * fix named primaries * default to gamma22 * mark mastering primaries as supported * remove xx-cm and frog support * immutable primaries and image descriptions * clang-format --- src/protocols/ColorManagement.cpp | 68 ++-- src/protocols/ColorManagement.hpp | 13 +- src/protocols/FrogColorManagement.cpp | 181 --------- src/protocols/FrogColorManagement.hpp | 54 --- src/protocols/XXColorManagement.cpp | 666 -------------------------------- src/protocols/XXColorManagement.hpp | 188 --------- src/protocols/core/Compositor.cpp | 2 +- src/protocols/core/Compositor.hpp | 3 +- src/protocols/types/ColorManagement.cpp | 100 ++++- src/protocols/types/ColorManagement.hpp | 89 ++++- 10 files changed, 189 insertions(+), 1175 deletions(-) delete mode 100644 src/protocols/FrogColorManagement.cpp delete mode 100644 src/protocols/FrogColorManagement.hpp delete mode 100644 src/protocols/XXColorManagement.cpp delete mode 100644 src/protocols/XXColorManagement.hpp (limited to 'src/protocols') diff --git a/src/protocols/ColorManagement.cpp b/src/protocols/ColorManagement.cpp index 4215a5e7..84280c71 100644 --- a/src/protocols/ColorManagement.cpp +++ b/src/protocols/ColorManagement.cpp @@ -18,12 +18,12 @@ CColorManager::CColorManager(SP resource) : m_resource(resour m_resource->sendSupportedFeature(WP_COLOR_MANAGER_V1_FEATURE_SET_PRIMARIES); m_resource->sendSupportedFeature(WP_COLOR_MANAGER_V1_FEATURE_SET_LUMINANCES); m_resource->sendSupportedFeature(WP_COLOR_MANAGER_V1_FEATURE_WINDOWS_SCRGB); + m_resource->sendSupportedFeature(WP_COLOR_MANAGER_V1_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES); + m_resource->sendSupportedFeature(WP_COLOR_MANAGER_V1_FEATURE_EXTENDED_TARGET_VOLUME); if (PROTO::colorManagement->m_debug) { m_resource->sendSupportedFeature(WP_COLOR_MANAGER_V1_FEATURE_ICC_V2_V4); m_resource->sendSupportedFeature(WP_COLOR_MANAGER_V1_FEATURE_SET_TF_POWER); - m_resource->sendSupportedFeature(WP_COLOR_MANAGER_V1_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES); - m_resource->sendSupportedFeature(WP_COLOR_MANAGER_V1_FEATURE_EXTENDED_TARGET_VOLUME); } m_resource->sendSupportedPrimariesNamed(WP_COLOR_MANAGER_V1_PRIMARIES_SRGB); @@ -35,10 +35,7 @@ CColorManager::CColorManager(SP resource) : m_resource(resour m_resource->sendSupportedPrimariesNamed(WP_COLOR_MANAGER_V1_PRIMARIES_DCI_P3); m_resource->sendSupportedPrimariesNamed(WP_COLOR_MANAGER_V1_PRIMARIES_DISPLAY_P3); m_resource->sendSupportedPrimariesNamed(WP_COLOR_MANAGER_V1_PRIMARIES_ADOBE_RGB); - - if (PROTO::colorManagement->m_debug) { - m_resource->sendSupportedPrimariesNamed(WP_COLOR_MANAGER_V1_PRIMARIES_CIE1931_XYZ); - } + m_resource->sendSupportedPrimariesNamed(WP_COLOR_MANAGER_V1_PRIMARIES_CIE1931_XYZ); m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB); m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_GAMMA22); @@ -171,14 +168,10 @@ CColorManager::CColorManager(SP resource) : m_resource(resour return; } - RESOURCE->m_self = RESOURCE; - RESOURCE->m_settings.windowsScRGB = true; - RESOURCE->m_settings.primariesNamed = NColorManagement::CM_PRIMARIES_SRGB; - RESOURCE->m_settings.primariesNameSet = true; - RESOURCE->m_settings.primaries = NColorPrimaries::BT709; - RESOURCE->m_settings.transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_EXT_LINEAR; - RESOURCE->m_settings.luminances.reference = 203; - RESOURCE->resource()->sendReady(RESOURCE->m_settings.updateId()); + RESOURCE->m_self = RESOURCE; + RESOURCE->m_settings = SCRGB_IMAGE_DESCRIPTION; + + RESOURCE->resource()->sendReady(RESOURCE->m_settings->id()); }); m_resource->setOnDestroy([this](CWpColorManagerV1* r) { PROTO::colorManagement->destroyResource(this); }); @@ -223,7 +216,7 @@ CColorManagementOutput::CColorManagementOutput(SP re RESOURCE->m_resource->sendFailed(WP_IMAGE_DESCRIPTION_V1_CAUSE_NO_OUTPUT, "No output"); else { RESOURCE->m_settings = m_output->m_monitor->m_imageDescription; - RESOURCE->m_resource->sendReady(RESOURCE->m_settings.updateId()); + RESOURCE->m_resource->sendReady(RESOURCE->m_settings->id()); } }); } @@ -236,10 +229,6 @@ wl_client* CColorManagementOutput::client() { return m_client; } -CColorManagementSurface::CColorManagementSurface(SP surface_) : m_surface(surface_) { - // only for frog cm until wayland cm is adopted -} - CColorManagementSurface::CColorManagementSurface(SP resource, SP surface_) : m_surface(surface_), m_resource(resource) { if UNLIKELY (!good()) return; @@ -280,7 +269,7 @@ CColorManagementSurface::CColorManagementSurface(SP }); m_resource->setUnsetImageDescription([this](CWpColorManagementSurfaceV1* r) { LOGM(Log::TRACE, "Unset image description for surface={}", (uintptr_t)r); - m_imageDescription = SImageDescription{}; + m_imageDescription = DEFAULT_IMAGE_DESCRIPTION; setHasImageDescription(false); }); } @@ -296,7 +285,8 @@ wl_client* CColorManagementSurface::client() { const SImageDescription& CColorManagementSurface::imageDescription() { if (!hasImageDescription()) LOGM(Log::WARN, "Reading imageDescription while none set. Returns default or empty values"); - return m_imageDescription; + + return m_imageDescription->value(); } bool CColorManagementSurface::hasImageDescription() { @@ -327,13 +317,14 @@ bool CColorManagementSurface::needsHdrMetadataUpdate() { } bool CColorManagementSurface::isHDR() { - return m_imageDescription.transferFunction == CM_TRANSFER_FUNCTION_ST2084_PQ || m_imageDescription.transferFunction == CM_TRANSFER_FUNCTION_HLG || isWindowsScRGB(); + return m_imageDescription->value().transferFunction == CM_TRANSFER_FUNCTION_ST2084_PQ || m_imageDescription->value().transferFunction == CM_TRANSFER_FUNCTION_HLG || + isWindowsScRGB(); } bool CColorManagementSurface::isWindowsScRGB() { - return m_imageDescription.windowsScRGB || + return m_imageDescription->value().windowsScRGB || // autodetect scRGB, might be incorrect - (m_imageDescription.primariesNamed == CM_PRIMARIES_SRGB && m_imageDescription.transferFunction == CM_TRANSFER_FUNCTION_EXT_LINEAR); + (m_imageDescription->value().primariesNamed == CM_PRIMARIES_SRGB && m_imageDescription->value().transferFunction == CM_TRANSFER_FUNCTION_EXT_LINEAR); } CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SP resource, SP surface_) : @@ -372,7 +363,7 @@ CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SPm_self = RESOURCE; RESOURCE->m_settings = m_surface->getPreferredImageDescription(); - RESOURCE->resource()->sendReady(RESOURCE->m_settings.updateId()); + RESOURCE->resource()->sendReady(RESOURCE->m_settings->id()); }); m_resource->setGetPreferredParametric([this](CWpColorManagementSurfaceFeedbackV1* r, uint32_t id) { @@ -394,9 +385,9 @@ CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SPm_self = RESOURCE; RESOURCE->m_settings = m_surface->getPreferredImageDescription(); - m_currentPreferredId = RESOURCE->m_settings.updateId(); + m_currentPreferredId = RESOURCE->m_settings->id(); - if (!PROTO::colorManagement->m_debug && RESOURCE->m_settings.icc.fd >= 0) { + if (!PROTO::colorManagement->m_debug && RESOURCE->m_settings->value().icc.fd >= 0) { LOGM(Log::ERR, "FIXME: parse icc profile"); r->error(WP_COLOR_MANAGER_V1_ERROR_UNSUPPORTED_FEATURE, "ICC profiles are not supported"); return; @@ -411,7 +402,7 @@ CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SPm_enteredOutputs.size() == 1) { - const auto newId = m_surface->getPreferredImageDescription().updateId(); + const auto newId = m_surface->getPreferredImageDescription()->id(); if (m_currentPreferredId != newId) m_resource->sendPreferredChanged(newId); } @@ -460,8 +451,8 @@ CColorManagementIccCreator::CColorManagementIccCreator(SPm_self = RESOURCE; - RESOURCE->m_settings = m_settings; - RESOURCE->resource()->sendReady(m_settings.updateId()); + RESOURCE->m_settings = CImageDescription::from(m_settings); + RESOURCE->resource()->sendReady(RESOURCE->m_settings->id()); PROTO::colorManagement->destroyResource(this); }); @@ -514,8 +505,8 @@ CColorManagementParametricCreator::CColorManagementParametricCreator(SPm_self = RESOURCE; - RESOURCE->m_settings = m_settings; - RESOURCE->resource()->sendReady(m_settings.updateId()); + RESOURCE->m_settings = CImageDescription::from(m_settings); + RESOURCE->resource()->sendReady(RESOURCE->m_settings->id()); PROTO::colorManagement->destroyResource(this); }); @@ -577,6 +568,7 @@ CColorManagementParametricCreator::CColorManagementParametricCreator(SPerror(WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_ALREADY_SET, "Mastering primaries already set"); return; } - if (!PROTO::colorManagement->m_debug) { - r->error(WP_COLOR_MANAGER_V1_ERROR_UNSUPPORTED_FEATURE, "Mastering primaries are not supported"); - return; - } + m_settings.masteringPrimaries = SPCPRimaries{.red = {.x = r_x / PRIMARIES_SCALE, .y = r_y / PRIMARIES_SCALE}, .green = {.x = g_x / PRIMARIES_SCALE, .y = g_y / PRIMARIES_SCALE}, .blue = {.x = b_x / PRIMARIES_SCALE, .y = b_y / PRIMARIES_SCALE}, @@ -653,10 +642,7 @@ CColorManagementParametricCreator::CColorManagementParametricCreator(SPerror(WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_INVALID_LUMINANCE, "Invalid luminances"); return; } - if (!PROTO::colorManagement->m_debug) { - r->error(WP_COLOR_MANAGER_V1_ERROR_UNSUPPORTED_FEATURE, "Mastering luminances are not supported"); - return; - } + m_settings.masteringLuminances = SImageDescription::SPCMasteringLuminances{.min = min, .max = max_lum}; m_valuesSet |= PC_MASTERING_LUMINANCES; }); @@ -705,7 +691,7 @@ CColorManagementImageDescription::CColorManagementImageDescription(SP(makeShared(r->client(), r->version(), id), m_settings); + auto RESOURCE = makeShared(makeShared(r->client(), r->version(), id), m_settings->value()); if UNLIKELY (!RESOURCE->good()) r->noMemory(); diff --git a/src/protocols/ColorManagement.hpp b/src/protocols/ColorManagement.hpp index dea9f74c..d43d5c12 100644 --- a/src/protocols/ColorManagement.hpp +++ b/src/protocols/ColorManagement.hpp @@ -46,7 +46,6 @@ class CColorManagementOutput { class CColorManagementSurface { public: - CColorManagementSurface(SP surface_); // temporary interface for frog CM CColorManagementSurface(SP resource, SP surface_); bool good(); @@ -67,14 +66,11 @@ class CColorManagementSurface { private: SP m_resource; wl_client* m_client = nullptr; - NColorManagement::SImageDescription m_imageDescription; - NColorManagement::SImageDescription m_lastImageDescription; + NColorManagement::PImageDescription m_imageDescription; + NColorManagement::PImageDescription m_lastImageDescription; bool m_hasImageDescription = false; bool m_needsNewMetadata = false; hdr_output_metadata m_hdrMetadata; - - friend class CXXColorManagementSurface; - friend class CFrogColorManagementSurface; }; class CColorManagementFeedbackSurface { @@ -157,7 +153,7 @@ class CColorManagementImageDescription { WP m_self; - NColorManagement::SImageDescription m_settings; + NColorManagement::PImageDescription m_settings; private: SP m_resource; @@ -216,9 +212,6 @@ class CColorManagementProtocol : public IWaylandProtocol { friend class CColorManagementIccCreator; friend class CColorManagementParametricCreator; friend class CColorManagementImageDescription; - - friend class CXXColorManagementSurface; - friend class CFrogColorManagementSurface; }; namespace PROTO { diff --git a/src/protocols/FrogColorManagement.cpp b/src/protocols/FrogColorManagement.cpp deleted file mode 100644 index 8506ce7b..00000000 --- a/src/protocols/FrogColorManagement.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "FrogColorManagement.hpp" -#include "color-management-v1.hpp" -#include "macros.hpp" -#include "protocols/ColorManagement.hpp" -#include "protocols/core/Subcompositor.hpp" -#include "protocols/types/ColorManagement.hpp" - -using namespace NColorManagement; - -static wpColorManagerV1TransferFunction getWPTransferFunction(frogColorManagedSurfaceTransferFunction tf) { - switch (tf) { - case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_UNDEFINED: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_BT1886; - case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_SRGB: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB; - case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_GAMMA_22: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_GAMMA22; - case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_ST2084_PQ: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ; - case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_SCRGB_LINEAR: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_LINEAR; - default: UNREACHABLE(); - } -} - -static wpColorManagerV1Primaries getWPPrimaries(frogColorManagedSurfacePrimaries primaries) { - return sc(primaries + 1); -} - -CFrogColorManager::CFrogColorManager(SP resource_) : m_resource(resource_) { - if UNLIKELY (!good()) - return; - - m_resource->setDestroy([](CFrogColorManagementFactoryV1* r) { LOGM(Log::TRACE, "Destroy frog_color_management at {:x} (generated default)", (uintptr_t)r); }); - m_resource->setOnDestroy([this](CFrogColorManagementFactoryV1* r) { PROTO::frogColorManagement->destroyResource(this); }); - - m_resource->setGetColorManagedSurface([](CFrogColorManagementFactoryV1* r, wl_resource* surface, uint32_t id) { - LOGM(Log::TRACE, "Get surface for id={}, surface={}", id, (uintptr_t)surface); - auto SURF = CWLSurfaceResource::fromResource(surface); - - if (!SURF) { - LOGM(Log::ERR, "No surface for resource {}", (uintptr_t)surface); - r->error(-1, "Invalid surface (2)"); - return; - } - - const auto RESOURCE = - PROTO::frogColorManagement->m_surfaces.emplace_back(makeShared(makeShared(r->client(), r->version(), id), SURF)); - if UNLIKELY (!RESOURCE->good()) { - r->noMemory(); - PROTO::frogColorManagement->m_surfaces.pop_back(); - return; - } - - RESOURCE->m_self = RESOURCE; - }); -} - -bool CFrogColorManager::good() { - return m_resource->resource(); -} - -CFrogColorManagementSurface::CFrogColorManagementSurface(SP resource_, SP surface_) : m_surface(surface_), m_resource(resource_) { - if UNLIKELY (!good()) - return; - - m_client = m_resource->client(); - - if (!m_surface->m_colorManagement.valid()) { - const auto RESOURCE = PROTO::colorManagement->m_surfaces.emplace_back(makeShared(surface_)); - if UNLIKELY (!RESOURCE) { - m_resource->noMemory(); - PROTO::colorManagement->m_surfaces.pop_back(); - return; - } - - RESOURCE->m_self = RESOURCE; - - m_surface->m_colorManagement = RESOURCE; - - m_resource->setOnDestroy([this](CFrogColorManagedSurface* r) { - LOGM(Log::TRACE, "Destroy frog cm and xx cm for surface {}", (uintptr_t)m_surface); - if (m_surface.valid()) - PROTO::colorManagement->destroyResource(m_surface->m_colorManagement.get()); - PROTO::frogColorManagement->destroyResource(this); - }); - } else - m_resource->setOnDestroy([this](CFrogColorManagedSurface* r) { - LOGM(Log::TRACE, "Destroy frog cm surface {}", (uintptr_t)m_surface); - PROTO::frogColorManagement->destroyResource(this); - }); - - m_resource->setDestroy([this](CFrogColorManagedSurface* r) { - LOGM(Log::TRACE, "Destroy frog cm surface {}", (uintptr_t)m_surface); - PROTO::frogColorManagement->destroyResource(this); - }); - - m_resource->setSetKnownTransferFunction([this](CFrogColorManagedSurface* r, frogColorManagedSurfaceTransferFunction tf) { - LOGM(Log::TRACE, "Set frog cm transfer function {} for {}", (uint32_t)tf, m_surface->id()); - switch (tf) { - case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_ST2084_PQ: - m_surface->m_colorManagement->m_imageDescription.transferFunction = - convertTransferFunction(getWPTransferFunction(FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_ST2084_PQ)); - break; - ; - case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_GAMMA_22: - if (m_pqIntentSent) { - LOGM(Log::TRACE, - "FIXME: assuming broken enum value 2 (FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_GAMMA_22) referring to eotf value 2 (TRANSFER_FUNCTION_ST2084_PQ)"); - m_surface->m_colorManagement->m_imageDescription.transferFunction = - convertTransferFunction(getWPTransferFunction(FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_ST2084_PQ)); - break; - }; - [[fallthrough]]; - case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_UNDEFINED: - case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_SCRGB_LINEAR: LOGM(Log::TRACE, "FIXME: add tf support for {}", (uint32_t)tf); [[fallthrough]]; - case FROG_COLOR_MANAGED_SURFACE_TRANSFER_FUNCTION_SRGB: - m_surface->m_colorManagement->m_imageDescription.transferFunction = convertTransferFunction(getWPTransferFunction(tf)); - - m_surface->m_colorManagement->setHasImageDescription(true); - } - }); - m_resource->setSetKnownContainerColorVolume([this](CFrogColorManagedSurface* r, frogColorManagedSurfacePrimaries primariesName) { - LOGM(Log::TRACE, "Set frog cm primaries {}", (uint32_t)primariesName); - switch (primariesName) { - case FROG_COLOR_MANAGED_SURFACE_PRIMARIES_UNDEFINED: - case FROG_COLOR_MANAGED_SURFACE_PRIMARIES_REC709: m_surface->m_colorManagement->m_imageDescription.primaries = NColorPrimaries::BT709; break; - case FROG_COLOR_MANAGED_SURFACE_PRIMARIES_REC2020: m_surface->m_colorManagement->m_imageDescription.primaries = NColorPrimaries::BT2020; break; - } - m_surface->m_colorManagement->m_imageDescription.primariesNamed = convertPrimaries(getWPPrimaries(primariesName)); - - m_surface->m_colorManagement->setHasImageDescription(true); - }); - m_resource->setSetRenderIntent([this](CFrogColorManagedSurface* r, frogColorManagedSurfaceRenderIntent intent) { - LOGM(Log::TRACE, "Set frog cm intent {}", (uint32_t)intent); - m_pqIntentSent = intent == FROG_COLOR_MANAGED_SURFACE_RENDER_INTENT_PERCEPTUAL; - m_surface->m_colorManagement->setHasImageDescription(true); - }); - m_resource->setSetHdrMetadata([this](CFrogColorManagedSurface* r, uint32_t r_x, uint32_t r_y, uint32_t g_x, uint32_t g_y, uint32_t b_x, uint32_t b_y, uint32_t w_x, - uint32_t w_y, uint32_t max_lum, uint32_t min_lum, uint32_t cll, uint32_t fall) { - LOGM(Log::TRACE, "Set frog primaries r:{},{} g:{},{} b:{},{} w:{},{} luminances {} - {} cll {} fall {}", r_x, r_y, g_x, g_y, b_x, b_y, w_x, w_y, min_lum, max_lum, cll, - fall); - m_surface->m_colorManagement->m_imageDescription.masteringPrimaries = SPCPRimaries{.red = {.x = r_x / 50000.0f, .y = r_y / 50000.0f}, - .green = {.x = g_x / 50000.0f, .y = g_y / 50000.0f}, - .blue = {.x = b_x / 50000.0f, .y = b_y / 50000.0f}, - .white = {.x = w_x / 50000.0f, .y = w_y / 50000.0f}}; - m_surface->m_colorManagement->m_imageDescription.masteringLuminances.min = min_lum / 10000.0f; - m_surface->m_colorManagement->m_imageDescription.masteringLuminances.max = max_lum; - m_surface->m_colorManagement->m_imageDescription.maxCLL = cll; - m_surface->m_colorManagement->m_imageDescription.maxFALL = fall; - - m_surface->m_colorManagement->setHasImageDescription(true); - }); -} - -bool CFrogColorManagementSurface::good() { - return m_resource->resource(); -} - -wl_client* CFrogColorManagementSurface::client() { - return m_client; -} - -CFrogColorManagementProtocol::CFrogColorManagementProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { - ; -} - -void CFrogColorManagementProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_managers.emplace_back(makeShared(makeShared(client, ver, id))); - - if UNLIKELY (!RESOURCE->good()) { - wl_client_post_no_memory(client); - m_managers.pop_back(); - return; - } - - LOGM(Log::TRACE, "New frog_color_management at {:x}", (uintptr_t)RESOURCE.get()); -} - -void CFrogColorManagementProtocol::destroyResource(CFrogColorManager* resource) { - std::erase_if(m_managers, [&](const auto& other) { return other.get() == resource; }); -} - -void CFrogColorManagementProtocol::destroyResource(CFrogColorManagementSurface* resource) { - std::erase_if(m_surfaces, [&](const auto& other) { return other.get() == resource; }); -} diff --git a/src/protocols/FrogColorManagement.hpp b/src/protocols/FrogColorManagement.hpp deleted file mode 100644 index 32e2202c..00000000 --- a/src/protocols/FrogColorManagement.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include "WaylandProtocol.hpp" -#include "protocols/core/Compositor.hpp" -#include "frog-color-management-v1.hpp" - -class CFrogColorManager { - public: - CFrogColorManager(SP resource_); - - bool good(); - - private: - SP m_resource; -}; - -class CFrogColorManagementSurface { - public: - CFrogColorManagementSurface(SP resource_, SP surface_); - - bool good(); - wl_client* client(); - - WP m_self; - WP m_surface; - - bool m_pqIntentSent = false; - - private: - SP m_resource; - wl_client* m_client = nullptr; -}; - -class CFrogColorManagementProtocol : public IWaylandProtocol { - public: - CFrogColorManagementProtocol(const wl_interface* iface, const int& ver, const std::string& name); - - virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); - - private: - void destroyResource(CFrogColorManager* resource); - void destroyResource(CFrogColorManagementSurface* resource); - - std::vector> m_managers; - std::vector> m_surfaces; - - friend class CFrogColorManager; - friend class CFrogColorManagementSurface; -}; - -namespace PROTO { - inline UP frogColorManagement; -}; diff --git a/src/protocols/XXColorManagement.cpp b/src/protocols/XXColorManagement.cpp deleted file mode 100644 index 92b30f7a..00000000 --- a/src/protocols/XXColorManagement.cpp +++ /dev/null @@ -1,666 +0,0 @@ -#include "XXColorManagement.hpp" -#include "../Compositor.hpp" -#include "ColorManagement.hpp" -#include "color-management-v1.hpp" -#include "types/ColorManagement.hpp" -#include "xx-color-management-v4.hpp" - -using namespace NColorManagement; - -static wpColorManagerV1TransferFunction getWPTransferFunction(xxColorManagerV4TransferFunction tf) { - switch (tf) { - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT709: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT1361: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_BT1886; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA22: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_GAMMA22; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA28: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_GAMMA28; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST240: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST240; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LINEAR: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_LINEAR; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_100: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_LOG_100; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_316: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_LOG_316; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_XVYCC: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_XVYCC; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_EXT_SRGB: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_SRGB; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST428: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST428; - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_HLG: return WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_HLG; - default: UNREACHABLE(); - } -} - -static wpColorManagerV1Primaries getWPPrimaries(xxColorManagerV4Primaries primaries) { - return sc(primaries + 1); -} - -CXXColorManager::CXXColorManager(SP resource_) : m_resource(resource_) { - if UNLIKELY (!good()) - return; - - m_resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_PARAMETRIC); - m_resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_EXTENDED_TARGET_VOLUME); - m_resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_SET_MASTERING_DISPLAY_PRIMARIES); - m_resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_SET_PRIMARIES); - m_resource->sendSupportedFeature(XX_COLOR_MANAGER_V4_FEATURE_SET_LUMINANCES); - - m_resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_SRGB); - m_resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_PAL_M); - m_resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_PAL); - m_resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_NTSC); - m_resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_GENERIC_FILM); - m_resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_BT2020); - // resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_CIE1931_XYZ); - m_resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_DCI_P3); - m_resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_DISPLAY_P3); - m_resource->sendSupportedPrimariesNamed(XX_COLOR_MANAGER_V4_PRIMARIES_ADOBE_RGB); - - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA22); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA28); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_HLG); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LINEAR); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT709); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT1361); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST240); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_100); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_316); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_XVYCC); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_EXT_SRGB); - m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST428); - - m_resource->sendSupportedIntent(XX_COLOR_MANAGER_V4_RENDER_INTENT_PERCEPTUAL); - // resource->sendSupportedIntent(XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE); - // resource->sendSupportedIntent(XX_COLOR_MANAGER_V4_RENDER_INTENT_ABSOLUTE); - // resource->sendSupportedIntent(XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE_BPC); - - m_resource->setDestroy([](CXxColorManagerV4* r) { LOGM(Log::TRACE, "Destroy xx_color_manager at {:x} (generated default)", (uintptr_t)r); }); - m_resource->setGetOutput([](CXxColorManagerV4* r, uint32_t id, wl_resource* output) { - LOGM(Log::TRACE, "Get output for id={}, output={}", id, (uintptr_t)output); - const auto RESOURCE = - PROTO::xxColorManagement->m_outputs.emplace_back(makeShared(makeShared(r->client(), r->version(), id))); - - if UNLIKELY (!RESOURCE->good()) { - r->noMemory(); - PROTO::xxColorManagement->m_outputs.pop_back(); - return; - } - - RESOURCE->m_self = RESOURCE; - }); - m_resource->setGetSurface([](CXxColorManagerV4* r, uint32_t id, wl_resource* surface) { - LOGM(Log::TRACE, "Get surface for id={}, surface={}", id, (uintptr_t)surface); - auto SURF = CWLSurfaceResource::fromResource(surface); - - if (!SURF) { - LOGM(Log::ERR, "No surface for resource {}", (uintptr_t)surface); - r->error(-1, "Invalid surface (2)"); - return; - } - - if (SURF->m_colorManagement) { - r->error(XX_COLOR_MANAGER_V4_ERROR_SURFACE_EXISTS, "CM Surface already exists"); - return; - } - - const auto RESOURCE = - PROTO::xxColorManagement->m_surfaces.emplace_back(makeShared(makeShared(r->client(), r->version(), id), SURF)); - if UNLIKELY (!RESOURCE->good()) { - r->noMemory(); - PROTO::xxColorManagement->m_surfaces.pop_back(); - return; - } - - RESOURCE->m_self = RESOURCE; - }); - m_resource->setGetFeedbackSurface([](CXxColorManagerV4* r, uint32_t id, wl_resource* surface) { - LOGM(Log::TRACE, "Get feedback surface for id={}, surface={}", id, (uintptr_t)surface); - auto SURF = CWLSurfaceResource::fromResource(surface); - - if (!SURF) { - LOGM(Log::ERR, "No surface for resource {}", (uintptr_t)surface); - r->error(-1, "Invalid surface (2)"); - return; - } - - const auto RESOURCE = PROTO::xxColorManagement->m_feedbackSurfaces.emplace_back( - makeShared(makeShared(r->client(), r->version(), id), SURF)); - - if UNLIKELY (!RESOURCE->good()) { - r->noMemory(); - PROTO::xxColorManagement->m_feedbackSurfaces.pop_back(); - return; - } - - RESOURCE->m_self = RESOURCE; - }); - m_resource->setNewIccCreator([](CXxColorManagerV4* r, uint32_t id) { - LOGM(Log::WARN, "New ICC creator for id={} (unsupported)", id); - r->error(XX_COLOR_MANAGER_V4_ERROR_UNSUPPORTED_FEATURE, "ICC profiles are not supported"); - }); - m_resource->setNewParametricCreator([](CXxColorManagerV4* r, uint32_t id) { - LOGM(Log::TRACE, "New parametric creator for id={}", id); - - const auto RESOURCE = PROTO::xxColorManagement->m_parametricCreators.emplace_back( - makeShared(makeShared(r->client(), r->version(), id))); - - if UNLIKELY (!RESOURCE->good()) { - r->noMemory(); - PROTO::xxColorManagement->m_parametricCreators.pop_back(); - return; - } - - RESOURCE->m_self = RESOURCE; - }); - - m_resource->setOnDestroy([this](CXxColorManagerV4* r) { PROTO::xxColorManagement->destroyResource(this); }); -} - -bool CXXColorManager::good() { - return m_resource->resource(); -} - -CXXColorManagementOutput::CXXColorManagementOutput(SP resource_) : m_resource(resource_) { - if UNLIKELY (!good()) - return; - - m_client = m_resource->client(); - - m_resource->setDestroy([this](CXxColorManagementOutputV4* r) { PROTO::xxColorManagement->destroyResource(this); }); - m_resource->setOnDestroy([this](CXxColorManagementOutputV4* r) { PROTO::xxColorManagement->destroyResource(this); }); - - m_resource->setGetImageDescription([this](CXxColorManagementOutputV4* r, uint32_t id) { - LOGM(Log::TRACE, "Get image description for output={}, id={}", (uintptr_t)r, id); - if (m_imageDescription.valid()) - PROTO::xxColorManagement->destroyResource(m_imageDescription.get()); - - const auto RESOURCE = PROTO::xxColorManagement->m_imageDescriptions.emplace_back( - makeShared(makeShared(r->client(), r->version(), id), true)); - - if UNLIKELY (!RESOURCE->good()) { - r->noMemory(); - PROTO::xxColorManagement->m_imageDescriptions.pop_back(); - return; - } - - RESOURCE->m_self = RESOURCE; - }); -} - -bool CXXColorManagementOutput::good() { - return m_resource->resource(); -} - -wl_client* CXXColorManagementOutput::client() { - return m_client; -} - -CXXColorManagementSurface::CXXColorManagementSurface(SP surface_) : m_surface(surface_) { - // only for frog cm until wayland cm is adopted -} - -CXXColorManagementSurface::CXXColorManagementSurface(SP resource_, SP surface_) : m_surface(surface_), m_resource(resource_) { - if UNLIKELY (!good()) - return; - - m_client = m_resource->client(); - - if (!m_surface->m_colorManagement.valid()) { - const auto RESOURCE = PROTO::colorManagement->m_surfaces.emplace_back(makeShared(surface_)); - if UNLIKELY (!RESOURCE) { - m_resource->noMemory(); - PROTO::colorManagement->m_surfaces.pop_back(); - return; - } - - RESOURCE->m_self = RESOURCE; - - m_surface->m_colorManagement = RESOURCE; - - m_resource->setOnDestroy([this](CXxColorManagementSurfaceV4* r) { - LOGM(Log::TRACE, "Destroy wp cm and xx cm for surface {}", (uintptr_t)m_surface); - if (m_surface.valid()) - PROTO::colorManagement->destroyResource(m_surface->m_colorManagement.get()); - PROTO::xxColorManagement->destroyResource(this); - }); - } else - m_resource->setOnDestroy([this](CXxColorManagementSurfaceV4* r) { - LOGM(Log::TRACE, "Destroy xx cm surface {}", (uintptr_t)m_surface); - PROTO::xxColorManagement->destroyResource(this); - }); - - m_resource->setDestroy([this](CXxColorManagementSurfaceV4* r) { - LOGM(Log::TRACE, "Destroy xx cm surface {}", (uintptr_t)m_surface); - PROTO::xxColorManagement->destroyResource(this); - }); - - m_resource->setSetImageDescription([this](CXxColorManagementSurfaceV4* r, wl_resource* image_description, uint32_t render_intent) { - LOGM(Log::TRACE, "Set image description for surface={}, desc={}, intent={}", (uintptr_t)r, (uintptr_t)image_description, render_intent); - - const auto PO = sc(wl_resource_get_user_data(image_description)); - if (!PO) { // FIXME check validity - r->error(XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_IMAGE_DESCRIPTION, "Image description creation failed"); - return; - } - if (render_intent != XX_COLOR_MANAGER_V4_RENDER_INTENT_PERCEPTUAL) { - r->error(XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_RENDER_INTENT, "Unsupported render intent"); - return; - } - - const auto imageDescription = - std::ranges::find_if(PROTO::xxColorManagement->m_imageDescriptions, [&](const auto& other) { return other->resource()->resource() == image_description; }); - if (imageDescription == PROTO::xxColorManagement->m_imageDescriptions.end()) { - r->error(XX_COLOR_MANAGEMENT_SURFACE_V4_ERROR_IMAGE_DESCRIPTION, "Image description not found"); - return; - } - - if (m_surface.valid()) { - m_surface->m_colorManagement->m_imageDescription = imageDescription->get()->m_settings; - m_surface->m_colorManagement->setHasImageDescription(true); - } else - LOGM(Log::ERR, "Set image description for invalid surface"); - }); - m_resource->setUnsetImageDescription([this](CXxColorManagementSurfaceV4* r) { - LOGM(Log::TRACE, "Unset image description for surface={}", (uintptr_t)r); - if (m_surface.valid()) { - m_surface->m_colorManagement->m_imageDescription = SImageDescription{}; - m_surface->m_colorManagement->setHasImageDescription(false); - } else - LOGM(Log::ERR, "Unset image description for invalid surface"); - }); -} - -bool CXXColorManagementSurface::good() { - return m_resource && m_resource->resource(); -} - -wl_client* CXXColorManagementSurface::client() { - return m_client; -} - -const SImageDescription& CXXColorManagementSurface::imageDescription() { - if (!hasImageDescription()) - LOGM(Log::WARN, "Reading imageDescription while none set. Returns default or empty values"); - return m_imageDescription; -} - -bool CXXColorManagementSurface::hasImageDescription() { - return m_hasImageDescription; -} - -void CXXColorManagementSurface::setHasImageDescription(bool has) { - m_hasImageDescription = has; - m_needsNewMetadata = true; -} - -const hdr_output_metadata& CXXColorManagementSurface::hdrMetadata() { - return m_hdrMetadata; -} - -void CXXColorManagementSurface::setHDRMetadata(const hdr_output_metadata& metadata) { - m_hdrMetadata = metadata; - m_needsNewMetadata = false; -} - -bool CXXColorManagementSurface::needsHdrMetadataUpdate() { - return m_needsNewMetadata; -} - -CXXColorManagementFeedbackSurface::CXXColorManagementFeedbackSurface(SP resource_, SP surface_) : - m_surface(surface_), m_resource(resource_) { - if UNLIKELY (!good()) - return; - - m_client = m_resource->client(); - - m_resource->setDestroy([this](CXxColorManagementFeedbackSurfaceV4* r) { - LOGM(Log::TRACE, "Destroy xx cm feedback surface {}", (uintptr_t)m_surface); - if (m_currentPreferred.valid()) - PROTO::xxColorManagement->destroyResource(m_currentPreferred.get()); - PROTO::xxColorManagement->destroyResource(this); - }); - m_resource->setOnDestroy([this](CXxColorManagementFeedbackSurfaceV4* r) { - LOGM(Log::TRACE, "Destroy xx cm feedback surface {}", (uintptr_t)m_surface); - if (m_currentPreferred.valid()) - PROTO::xxColorManagement->destroyResource(m_currentPreferred.get()); - PROTO::xxColorManagement->destroyResource(this); - }); - - m_resource->setGetPreferred([this](CXxColorManagementFeedbackSurfaceV4* r, uint32_t id) { - LOGM(Log::TRACE, "Get preferred for id {}", id); - - if (m_currentPreferred.valid()) - PROTO::xxColorManagement->destroyResource(m_currentPreferred.get()); - - const auto RESOURCE = PROTO::xxColorManagement->m_imageDescriptions.emplace_back( - makeShared(makeShared(r->client(), r->version(), id), true)); - - if UNLIKELY (!RESOURCE->good()) { - r->noMemory(); - PROTO::xxColorManagement->m_imageDescriptions.pop_back(); - return; - } - - RESOURCE->m_self = RESOURCE; - m_currentPreferred = RESOURCE; - - m_currentPreferred->m_settings = g_pCompositor->getPreferredImageDescription(); - - RESOURCE->resource()->sendReady(id); - }); -} - -bool CXXColorManagementFeedbackSurface::good() { - return m_resource->resource(); -} - -wl_client* CXXColorManagementFeedbackSurface::client() { - return m_client; -} - -CXXColorManagementParametricCreator::CXXColorManagementParametricCreator(SP resource_) : m_resource(resource_) { - if UNLIKELY (!good()) - return; - // - m_client = m_resource->client(); - - m_resource->setOnDestroy([this](CXxImageDescriptionCreatorParamsV4* r) { PROTO::xxColorManagement->destroyResource(this); }); - - m_resource->setCreate([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t id) { - LOGM(Log::TRACE, "Create image description from params for id {}", id); - - // FIXME actually check completeness - if (!m_valuesSet) { - r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INCOMPLETE_SET, "Missing required settings"); - return; - } - - // FIXME actually check consistency - if (!m_valuesSet) { - r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INCONSISTENT_SET, "Set is not consistent"); - return; - } - - const auto RESOURCE = PROTO::xxColorManagement->m_imageDescriptions.emplace_back( - makeShared(makeShared(r->client(), r->version(), id), false)); - - if UNLIKELY (!RESOURCE->good()) { - r->noMemory(); - PROTO::xxColorManagement->m_imageDescriptions.pop_back(); - return; - } - - // FIXME actually check support - if (!m_valuesSet) { - RESOURCE->resource()->sendFailed(XX_IMAGE_DESCRIPTION_V4_CAUSE_UNSUPPORTED, "unsupported"); - return; - } - - RESOURCE->m_self = RESOURCE; - RESOURCE->m_settings = m_settings; - RESOURCE->resource()->sendReady(id); - - PROTO::xxColorManagement->destroyResource(this); - }); - m_resource->setSetTfNamed([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t tf) { - LOGM(Log::TRACE, "Set image description transfer function to {}", tf); - if (m_valuesSet & PC_TF) { - r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Transfer function already set"); - return; - } - - switch (tf) { - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA22: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_GAMMA28: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_HLG: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LINEAR: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT709: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT1361: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST240: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_100: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_316: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_XVYCC: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_EXT_SRGB: - case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST428: break; - default: r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_TF, "Unsupported transfer function"); return; - } - - m_settings.transferFunction = convertTransferFunction(getWPTransferFunction(sc(tf))); - m_valuesSet |= PC_TF; - }); - m_resource->setSetTfPower([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t eexp) { - LOGM(Log::TRACE, "Set image description tf power to {}", eexp); - if (m_valuesSet & PC_TF_POWER) { - r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Transfer function power already set"); - return; - } - m_settings.transferFunctionPower = eexp / 10000.0f; - m_valuesSet |= PC_TF_POWER; - }); - m_resource->setSetPrimariesNamed([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t primaries) { - LOGM(Log::TRACE, "Set image description primaries by name {}", primaries); - if (m_valuesSet & PC_PRIMARIES) { - r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Primaries already set"); - return; - } - - switch (primaries) { - case XX_COLOR_MANAGER_V4_PRIMARIES_SRGB: - case XX_COLOR_MANAGER_V4_PRIMARIES_PAL_M: - case XX_COLOR_MANAGER_V4_PRIMARIES_PAL: - case XX_COLOR_MANAGER_V4_PRIMARIES_NTSC: - case XX_COLOR_MANAGER_V4_PRIMARIES_GENERIC_FILM: - case XX_COLOR_MANAGER_V4_PRIMARIES_BT2020: - case XX_COLOR_MANAGER_V4_PRIMARIES_DCI_P3: - case XX_COLOR_MANAGER_V4_PRIMARIES_DISPLAY_P3: - case XX_COLOR_MANAGER_V4_PRIMARIES_ADOBE_RGB: - m_settings.primariesNameSet = true; - m_settings.primariesNamed = convertPrimaries(getWPPrimaries(sc(primaries))); - m_settings.primaries = getPrimaries(m_settings.primariesNamed); - m_valuesSet |= PC_PRIMARIES; - break; - default: r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_PRIMARIES, "Unsupported primaries"); - } - }); - m_resource->setSetPrimaries( - [this](CXxImageDescriptionCreatorParamsV4* r, int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y, int32_t b_x, int32_t b_y, int32_t w_x, int32_t w_y) { - LOGM(Log::TRACE, "Set image description primaries by values r:{},{} g:{},{} b:{},{} w:{},{}", r_x, r_y, g_x, g_y, b_x, b_y, w_x, w_y); - if (m_valuesSet & PC_PRIMARIES) { - r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Primaries already set"); - return; - } - m_settings.primariesNameSet = false; - m_settings.primaries = SPCPRimaries{.red = {.x = r_x, .y = r_y}, .green = {.x = g_x, .y = g_y}, .blue = {.x = b_x, .y = b_y}, .white = {.x = w_x, .y = w_y}}; - m_valuesSet |= PC_PRIMARIES; - }); - m_resource->setSetLuminances([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t min_lum, uint32_t max_lum, uint32_t reference_lum) { - auto min = min_lum / 10000.0f; - LOGM(Log::TRACE, "Set image description luminances to {} - {} ({})", min, max_lum, reference_lum); - if (m_valuesSet & PC_LUMINANCES) { - r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Luminances already set"); - return; - } - if (max_lum < reference_lum || reference_lum <= min) { - r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_LUMINANCE, "Invalid luminances"); - return; - } - m_settings.luminances = SImageDescription::SPCLuminances{.min = min, .max = max_lum, .reference = reference_lum}; - m_valuesSet |= PC_LUMINANCES; - }); - m_resource->setSetMasteringDisplayPrimaries( - [this](CXxImageDescriptionCreatorParamsV4* r, int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y, int32_t b_x, int32_t b_y, int32_t w_x, int32_t w_y) { - LOGM(Log::TRACE, "Set image description mastering primaries by values r:{},{} g:{},{} b:{},{} w:{},{}", r_x, r_y, g_x, g_y, b_x, b_y, w_x, w_y); - // if (valuesSet & PC_MASTERING_PRIMARIES) { - // r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Mastering primaries already set"); - // return; - // } - m_settings.masteringPrimaries = SPCPRimaries{.red = {.x = r_x, .y = r_y}, .green = {.x = g_x, .y = g_y}, .blue = {.x = b_x, .y = b_y}, .white = {.x = w_x, .y = w_y}}; - m_valuesSet |= PC_MASTERING_PRIMARIES; - }); - m_resource->setSetMasteringLuminance([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t min_lum, uint32_t max_lum) { - auto min = min_lum / 10000.0f; - LOGM(Log::TRACE, "Set image description mastering luminances to {} - {}", min, max_lum); - // if (valuesSet & PC_MASTERING_LUMINANCES) { - // r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Mastering luminances already set"); - // return; - // } - if (min > 0 && max_lum > 0 && max_lum <= min) { - r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_LUMINANCE, "Invalid luminances"); - return; - } - m_settings.masteringLuminances = SImageDescription::SPCMasteringLuminances{.min = min, .max = max_lum}; - m_valuesSet |= PC_MASTERING_LUMINANCES; - }); - m_resource->setSetMaxCll([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t max_cll) { - LOGM(Log::TRACE, "Set image description max content light level to {}", max_cll); - // if (valuesSet & PC_CLL) { - // r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Max CLL already set"); - // return; - // } - m_settings.maxCLL = max_cll; - m_valuesSet |= PC_CLL; - }); - m_resource->setSetMaxFall([this](CXxImageDescriptionCreatorParamsV4* r, uint32_t max_fall) { - LOGM(Log::TRACE, "Set image description max frame-average light level to {}", max_fall); - // if (valuesSet & PC_FALL) { - // r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_ALREADY_SET, "Max FALL already set"); - // return; - // } - m_settings.maxFALL = max_fall; - m_valuesSet |= PC_FALL; - }); -} - -bool CXXColorManagementParametricCreator::good() { - return m_resource->resource(); -} - -wl_client* CXXColorManagementParametricCreator::client() { - return m_client; -} - -CXXColorManagementImageDescription::CXXColorManagementImageDescription(SP resource_, bool allowGetInformation) : - m_resource(resource_), m_allowGetInformation(allowGetInformation) { - if UNLIKELY (!good()) - return; - - m_client = m_resource->client(); - - m_resource->setDestroy([this](CXxImageDescriptionV4* r) { PROTO::xxColorManagement->destroyResource(this); }); - m_resource->setOnDestroy([this](CXxImageDescriptionV4* r) { PROTO::xxColorManagement->destroyResource(this); }); - - m_resource->setGetInformation([this](CXxImageDescriptionV4* r, uint32_t id) { - LOGM(Log::TRACE, "Get image information for image={}, id={}", (uintptr_t)r, id); - if (!m_allowGetInformation) { - r->error(XX_IMAGE_DESCRIPTION_V4_ERROR_NO_INFORMATION, "Image descriptions doesn't allow get_information request"); - return; - } - - auto RESOURCE = makeShared(makeShared(r->client(), r->version(), id), m_settings); - - if UNLIKELY (!RESOURCE->good()) - r->noMemory(); - - // CXXColorManagementImageDescriptionInfo should send everything in the constructor and be ready for destroying at this point - RESOURCE.reset(); - }); -} - -bool CXXColorManagementImageDescription::good() { - return m_resource->resource(); -} - -wl_client* CXXColorManagementImageDescription::client() { - return m_client; -} - -SP CXXColorManagementImageDescription::resource() { - return m_resource; -} - -CXXColorManagementImageDescriptionInfo::CXXColorManagementImageDescriptionInfo(SP resource_, const SImageDescription& settings_) : - m_resource(resource_), m_settings(settings_) { - if UNLIKELY (!good()) - return; - - m_client = m_resource->client(); - - const auto toProto = [](float value) { return sc(std::round(value * 10000)); }; - - if (m_settings.icc.fd >= 0) - m_resource->sendIccFile(m_settings.icc.fd, m_settings.icc.length); - - // send preferred client paramateres - m_resource->sendPrimaries(toProto(m_settings.primaries.red.x), toProto(m_settings.primaries.red.y), toProto(m_settings.primaries.green.x), - toProto(m_settings.primaries.green.y), toProto(m_settings.primaries.blue.x), toProto(m_settings.primaries.blue.y), - toProto(m_settings.primaries.white.x), toProto(m_settings.primaries.white.y)); - if (m_settings.primariesNameSet) - m_resource->sendPrimariesNamed(m_settings.primariesNamed); - m_resource->sendTfPower(std::round(m_settings.transferFunctionPower * 10000)); - m_resource->sendTfNamed(m_settings.transferFunction); - m_resource->sendLuminances(std::round(m_settings.luminances.min * 10000), m_settings.luminances.max, m_settings.luminances.reference); - - // send expected display paramateres - m_resource->sendTargetPrimaries(toProto(m_settings.masteringPrimaries.red.x), toProto(m_settings.masteringPrimaries.red.y), toProto(m_settings.masteringPrimaries.green.x), - toProto(m_settings.masteringPrimaries.green.y), toProto(m_settings.masteringPrimaries.blue.x), toProto(m_settings.masteringPrimaries.blue.y), - toProto(m_settings.masteringPrimaries.white.x), toProto(m_settings.masteringPrimaries.white.y)); - m_resource->sendTargetLuminance(std::round(m_settings.masteringLuminances.min * 10000), m_settings.masteringLuminances.max); - m_resource->sendTargetMaxCll(m_settings.maxCLL); - m_resource->sendTargetMaxFall(m_settings.maxFALL); - - m_resource->sendDone(); -} - -bool CXXColorManagementImageDescriptionInfo::good() { - return m_resource->resource(); -} - -wl_client* CXXColorManagementImageDescriptionInfo::client() { - return m_client; -} - -CXXColorManagementProtocol::CXXColorManagementProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { - ; -} - -void CXXColorManagementProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { - const auto RESOURCE = m_managers.emplace_back(makeShared(makeShared(client, ver, id))); - - if UNLIKELY (!RESOURCE->good()) { - wl_client_post_no_memory(client); - m_managers.pop_back(); - return; - } - - LOGM(Log::TRACE, "New xx_color_manager at {:x}", (uintptr_t)RESOURCE.get()); -} - -void CXXColorManagementProtocol::onImagePreferredChanged() { - for (auto const& feedback : m_feedbackSurfaces) { - feedback->m_resource->sendPreferredChanged(); - } -} - -void CXXColorManagementProtocol::destroyResource(CXXColorManager* resource) { - std::erase_if(m_managers, [&](const auto& other) { return other.get() == resource; }); -} - -void CXXColorManagementProtocol::destroyResource(CXXColorManagementOutput* resource) { - std::erase_if(m_outputs, [&](const auto& other) { return other.get() == resource; }); -} - -void CXXColorManagementProtocol::destroyResource(CXXColorManagementSurface* resource) { - std::erase_if(m_surfaces, [&](const auto& other) { return other.get() == resource; }); -} - -void CXXColorManagementProtocol::destroyResource(CXXColorManagementFeedbackSurface* resource) { - std::erase_if(m_feedbackSurfaces, [&](const auto& other) { return other.get() == resource; }); -} - -void CXXColorManagementProtocol::destroyResource(CXXColorManagementParametricCreator* resource) { - std::erase_if(m_parametricCreators, [&](const auto& other) { return other.get() == resource; }); -} - -void CXXColorManagementProtocol::destroyResource(CXXColorManagementImageDescription* resource) { - std::erase_if(m_imageDescriptions, [&](const auto& other) { return other.get() == resource; }); -} diff --git a/src/protocols/XXColorManagement.hpp b/src/protocols/XXColorManagement.hpp deleted file mode 100644 index 0407730a..00000000 --- a/src/protocols/XXColorManagement.hpp +++ /dev/null @@ -1,188 +0,0 @@ -#pragma once - -#include -#include -#include -#include "WaylandProtocol.hpp" -#include "core/Compositor.hpp" -#include "xx-color-management-v4.hpp" -#include "types/ColorManagement.hpp" - -class CXXColorManager; -class CXXColorManagementOutput; -class CXXColorManagementImageDescription; -class CXXColorManagementProtocol; - -class CXXColorManager { - public: - CXXColorManager(SP resource_); - - bool good(); - - private: - SP m_resource; -}; - -class CXXColorManagementOutput { - public: - CXXColorManagementOutput(SP resource_); - - bool good(); - wl_client* client(); - - WP m_self; - WP m_imageDescription; - - private: - SP m_resource; - wl_client* m_client = nullptr; - - friend class CXXColorManagementProtocol; - friend class CXXColorManagementImageDescription; -}; - -class CXXColorManagementSurface { - public: - CXXColorManagementSurface(SP surface_); // temporary interface for frog CM - CXXColorManagementSurface(SP resource_, SP surface_); - - bool good(); - wl_client* client(); - - WP m_self; - WP m_surface; - - const NColorManagement::SImageDescription& imageDescription(); - bool hasImageDescription(); - void setHasImageDescription(bool has); - const hdr_output_metadata& hdrMetadata(); - void setHDRMetadata(const hdr_output_metadata& metadata); - bool needsHdrMetadataUpdate(); - - private: - SP m_resource; - wl_client* m_client = nullptr; - NColorManagement::SImageDescription m_imageDescription; - bool m_hasImageDescription = false; - bool m_needsNewMetadata = false; - hdr_output_metadata m_hdrMetadata; - - friend class CFrogColorManagementSurface; -}; - -class CXXColorManagementFeedbackSurface { - public: - CXXColorManagementFeedbackSurface(SP resource_, SP surface_); - - bool good(); - wl_client* client(); - - WP m_self; - WP m_surface; - - private: - SP m_resource; - wl_client* m_client = nullptr; - - WP m_currentPreferred; - - friend class CXXColorManagementProtocol; -}; - -class CXXColorManagementParametricCreator { - public: - CXXColorManagementParametricCreator(SP resource_); - - bool good(); - wl_client* client(); - - WP m_self; - - NColorManagement::SImageDescription m_settings; - - private: - enum eValuesSet : uint32_t { // NOLINT - PC_TF = (1 << 0), - PC_TF_POWER = (1 << 1), - PC_PRIMARIES = (1 << 2), - PC_LUMINANCES = (1 << 3), - PC_MASTERING_PRIMARIES = (1 << 4), - PC_MASTERING_LUMINANCES = (1 << 5), - PC_CLL = (1 << 6), - PC_FALL = (1 << 7), - }; - - SP m_resource; - wl_client* m_client = nullptr; - uint32_t m_valuesSet = 0; // enum eValuesSet -}; - -class CXXColorManagementImageDescription { - public: - CXXColorManagementImageDescription(SP resource_, bool allowGetInformation); - - bool good(); - wl_client* client(); - SP resource(); - - WP m_self; - - NColorManagement::SImageDescription m_settings; - - private: - SP m_resource; - wl_client* m_client = nullptr; - bool m_allowGetInformation = false; - - friend class CXXColorManagementOutput; -}; - -class CXXColorManagementImageDescriptionInfo { - public: - CXXColorManagementImageDescriptionInfo(SP resource_, const NColorManagement::SImageDescription& settings_); - - bool good(); - wl_client* client(); - - private: - SP m_resource; - wl_client* m_client = nullptr; - NColorManagement::SImageDescription m_settings; -}; - -class CXXColorManagementProtocol : public IWaylandProtocol { - public: - CXXColorManagementProtocol(const wl_interface* iface, const int& ver, const std::string& name); - - virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); - - void onImagePreferredChanged(); - - private: - void destroyResource(CXXColorManager* resource); - void destroyResource(CXXColorManagementOutput* resource); - void destroyResource(CXXColorManagementSurface* resource); - void destroyResource(CXXColorManagementFeedbackSurface* resource); - void destroyResource(CXXColorManagementParametricCreator* resource); - void destroyResource(CXXColorManagementImageDescription* resource); - - std::vector> m_managers; - std::vector> m_outputs; - std::vector> m_surfaces; - std::vector> m_feedbackSurfaces; - std::vector> m_parametricCreators; - std::vector> m_imageDescriptions; - - friend class CXXColorManager; - friend class CXXColorManagementOutput; - friend class CXXColorManagementSurface; - friend class CXXColorManagementFeedbackSurface; - friend class CXXColorManagementParametricCreator; - friend class CXXColorManagementImageDescription; - - friend class CFrogColorManagementSurface; -}; - -namespace PROTO { - inline UP xxColorManagement; -}; diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index c2d99176..b9e677af 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -556,7 +556,7 @@ void CWLSurfaceResource::commitState(SSurfaceState& state) { dropCurrentBuffer(); } -SImageDescription CWLSurfaceResource::getPreferredImageDescription() { +PImageDescription CWLSurfaceResource::getPreferredImageDescription() { static const auto PFORCE_HDR = CConfigValue("quirks:prefer_hdr"); const auto WINDOW = m_hlSurface ? Desktop::View::CWindow::fromView(m_hlSurface->view()) : nullptr; diff --git a/src/protocols/core/Compositor.hpp b/src/protocols/core/Compositor.hpp index 7b295aa7..89bfb31b 100644 --- a/src/protocols/core/Compositor.hpp +++ b/src/protocols/core/Compositor.hpp @@ -33,7 +33,6 @@ class CDRMSyncobjSurfaceResource; class CFifoResource; class CCommitTimerResource; class CColorManagementSurface; -class CFrogColorManagementSurface; class CContentType; class CWLCallbackResource { @@ -126,7 +125,7 @@ class CWLSurfaceResource { void presentFeedback(const Time::steady_tp& when, PHLMONITOR pMonitor, bool discarded = false); void scheduleState(WP state); void commitState(SSurfaceState& state); - NColorManagement::SImageDescription getPreferredImageDescription(); + NColorManagement::PImageDescription getPreferredImageDescription(); void sortSubsurfaces(); bool hasVisibleSubsurface(); diff --git a/src/protocols/types/ColorManagement.cpp b/src/protocols/types/ColorManagement.cpp index e6b470d0..5d23d1c9 100644 --- a/src/protocols/types/ColorManagement.cpp +++ b/src/protocols/types/ColorManagement.cpp @@ -1,11 +1,16 @@ #include "ColorManagement.hpp" +#include "../../macros.hpp" +#include #include +#include namespace NColorManagement { - static uint32_t lastImageID = 0; - static std::map knownDescriptionIds; // expected to be small + // expected to be small + static std::vector> knownPrimaries; + static std::vector> knownDescriptions; + static std::map, Hyprgraphics::CMatrix3> primariesConversion; - const SPCPRimaries& getPrimaries(ePrimaries name) { + const SPCPRimaries& getPrimaries(ePrimaries name) { switch (name) { case CM_PRIMARIES_SRGB: return NColorPrimaries::BT709; case CM_PRIMARIES_BT2020: return NColorPrimaries::BT2020; @@ -13,7 +18,7 @@ namespace NColorManagement { case CM_PRIMARIES_PAL: return NColorPrimaries::PAL; case CM_PRIMARIES_NTSC: return NColorPrimaries::NTSC; case CM_PRIMARIES_GENERIC_FILM: return NColorPrimaries::GENERIC_FILM; - case CM_PRIMARIES_CIE1931_XYZ: return NColorPrimaries::DEFAULT_PRIMARIES; // FIXME + case CM_PRIMARIES_CIE1931_XYZ: return NColorPrimaries::CIE1931_XYZ; case CM_PRIMARIES_DCI_P3: return NColorPrimaries::DCI_P3; case CM_PRIMARIES_DISPLAY_P3: return NColorPrimaries::DISPLAY_P3; case CM_PRIMARIES_ADOBE_RGB: return NColorPrimaries::ADOBE_RGB; @@ -21,26 +26,85 @@ namespace NColorManagement { } } - // TODO make image descriptions immutable and always set an id + CPrimaries::CPrimaries(const SPCPRimaries& primaries, const uint primariesId) : m_id(primariesId), m_primaries(primaries) { + m_primaries2XYZ = m_primaries.toXYZ(); + } - uint32_t SImageDescription::findId() const { - for (auto it = knownDescriptionIds.begin(); it != knownDescriptionIds.end(); ++it) { - if (it->second == *this) - return it->first; + WP CPrimaries::from(const SPCPRimaries& primaries) { + for (const auto& known : knownPrimaries) { + if (known->value() == primaries) + return known; } - const auto newId = ++lastImageID; - knownDescriptionIds.insert(std::make_pair(newId, *this)); - return newId; + knownPrimaries.emplace_back(CUniquePointer(new CPrimaries(primaries, knownPrimaries.size() + 1))); + return knownPrimaries.back(); + } + + WP CPrimaries::from(const ePrimaries name) { + return from(getPrimaries(name)); + } + + WP CPrimaries::from(const uint primariesId) { + ASSERT(primariesId <= knownPrimaries.size()); + return knownPrimaries[primariesId - 1]; + } + + const SPCPRimaries& CPrimaries::value() const { + return m_primaries; } - uint32_t SImageDescription::getId() const { - return id > 0 ? id : findId(); + uint CPrimaries::id() const { + return m_id; } - uint32_t SImageDescription::updateId() { - id = 0; - id = findId(); - return id; + const Hyprgraphics::CMatrix3& CPrimaries::toXYZ() const { + return m_primaries2XYZ; } + + const Hyprgraphics::CMatrix3& CPrimaries::convertMatrix(const WP dst) const { + const auto cacheKey = std::make_pair(m_id, dst->m_id); + if (!primariesConversion.contains(cacheKey)) + primariesConversion.insert(std::make_pair(cacheKey, m_primaries.convertMatrix(dst->m_primaries))); + + return primariesConversion[cacheKey]; + } + + CImageDescription::CImageDescription(const SImageDescription& imageDescription, const uint imageDescriptionId) : + m_id(imageDescriptionId), m_imageDescription(imageDescription) { + m_primariesId = CPrimaries::from(m_imageDescription.getPrimaries())->id(); + } + + PImageDescription CImageDescription::from(const SImageDescription& imageDescription) { + for (const auto& known : knownDescriptions) { + if (known->value() == imageDescription) + return known; + } + + knownDescriptions.emplace_back(CUniquePointer(new CImageDescription(imageDescription, knownDescriptions.size() + 1))); + return knownDescriptions.back(); + } + + PImageDescription CImageDescription::from(const uint imageDescriptionId) { + ASSERT(imageDescriptionId <= knownDescriptions.size()); + return knownDescriptions[imageDescriptionId - 1]; + } + + PImageDescription CImageDescription::with(const SImageDescription::SPCLuminances& luminances) const { + auto desc = m_imageDescription; + desc.luminances = luminances; + return CImageDescription::from(desc); + } + + const SImageDescription& CImageDescription::value() const { + return m_imageDescription; + } + + uint CImageDescription::id() const { + return m_id; + } + + WP CImageDescription::getPrimaries() const { + return CPrimaries::from(m_primariesId); + } + } \ No newline at end of file diff --git a/src/protocols/types/ColorManagement.hpp b/src/protocols/types/ColorManagement.hpp index 8bb30e8e..01077704 100644 --- a/src/protocols/types/ColorManagement.hpp +++ b/src/protocols/types/ColorManagement.hpp @@ -75,30 +75,35 @@ namespace NColorManagement { .blue = {.x = 0.15, .y = 0.06}, .white = {.x = 0.3127, .y = 0.3290}, }; + static const auto PAL_M = SPCPRimaries{ .red = {.x = 0.67, .y = 0.33}, .green = {.x = 0.21, .y = 0.71}, .blue = {.x = 0.14, .y = 0.08}, .white = {.x = 0.310, .y = 0.316}, }; + static const auto PAL = SPCPRimaries{ .red = {.x = 0.640, .y = 0.330}, .green = {.x = 0.290, .y = 0.600}, .blue = {.x = 0.150, .y = 0.060}, .white = {.x = 0.3127, .y = 0.3290}, }; + static const auto NTSC = SPCPRimaries{ .red = {.x = 0.630, .y = 0.340}, .green = {.x = 0.310, .y = 0.595}, .blue = {.x = 0.155, .y = 0.070}, .white = {.x = 0.3127, .y = 0.3290}, }; + static const auto GENERIC_FILM = SPCPRimaries{ .red = {.x = 0.243, .y = 0.692}, .green = {.x = 0.145, .y = 0.049}, .blue = {.x = 0.681, .y = 0.319}, // NOLINT(modernize-use-std-numbers) .white = {.x = 0.310, .y = 0.316}, }; + static const auto BT2020 = SPCPRimaries{ .red = {.x = 0.708, .y = 0.292}, .green = {.x = 0.170, .y = 0.797}, @@ -106,7 +111,12 @@ namespace NColorManagement { .white = {.x = 0.3127, .y = 0.3290}, }; - // FIXME CIE1931_XYZ + static const auto CIE1931_XYZ = SPCPRimaries{ + .red = {.x = 1.0, .y = 0.0}, + .green = {.x = 0.0, .y = 1.0}, + .blue = {.x = 0.0, .y = 0.0}, + .white = {.x = 1.0 / 3.0, .y = 1.0 / 3.0}, + }; static const auto DCI_P3 = SPCPRimaries{ .red = {.x = 0.680, .y = 0.320}, @@ -121,6 +131,7 @@ namespace NColorManagement { .blue = {.x = 0.150, .y = 0.060}, .white = {.x = 0.3127, .y = 0.3290}, }; + static const auto ADOBE_RGB = SPCPRimaries{ .red = {.x = 0.6400, .y = 0.3300}, .green = {.x = 0.2100, .y = 0.7100}, @@ -131,9 +142,27 @@ namespace NColorManagement { const SPCPRimaries& getPrimaries(ePrimaries name); - struct SImageDescription { - uint32_t id = 0; // FIXME needs id setting + class CPrimaries { + public: + static WP from(const SPCPRimaries& primaries); + static WP from(const ePrimaries name); + static WP from(const uint primariesId); + + const SPCPRimaries& value() const; + uint id() const; + + const Hyprgraphics::CMatrix3& toXYZ() const; // toXYZ() * rgb -> xyz + const Hyprgraphics::CMatrix3& convertMatrix(const WP dst) const; // convertMatrix(dst) * rgb with "this" primaries -> rgb with dst primaries + + private: + CPrimaries(const SPCPRimaries& primaries, const uint primariesId); + uint m_id; + SPCPRimaries m_primaries; + Hyprgraphics::CMatrix3 m_primaries2XYZ; + }; + + struct SImageDescription { struct SIccFile { int fd = -1; uint32_t length = 0; @@ -145,16 +174,14 @@ namespace NColorManagement { bool windowsScRGB = false; - eTransferFunction transferFunction = CM_TRANSFER_FUNCTION_SRGB; + eTransferFunction transferFunction = CM_TRANSFER_FUNCTION_GAMMA22; float transferFunctionPower = 1.0f; bool primariesNameSet = false; ePrimaries primariesNamed = CM_PRIMARIES_SRGB; // primaries are stored as FP values with the same scale as standard defines (0.0 - 1.0) // wayland protocol expects int32_t values multiplied by 1000000 - // xx protocol expects int32_t values multiplied by 10000 // drm expects uint16_t values multiplied by 50000 - // frog protocol expects drm values SPCPRimaries primaries, masteringPrimaries; // luminances in cd/m² @@ -179,11 +206,10 @@ namespace NColorManagement { uint32_t maxFALL = 0; bool operator==(const SImageDescription& d2) const { - return (id != 0 && id == d2.id) || - (icc == d2.icc && windowsScRGB == d2.windowsScRGB && transferFunction == d2.transferFunction && transferFunctionPower == d2.transferFunctionPower && - (primariesNameSet == d2.primariesNameSet && (primariesNameSet ? primariesNamed == d2.primariesNamed : primaries == d2.primaries)) && - masteringPrimaries == d2.masteringPrimaries && luminances == d2.luminances && masteringLuminances == d2.masteringLuminances && maxCLL == d2.maxCLL && - maxFALL == d2.maxFALL); + return icc == d2.icc && windowsScRGB == d2.windowsScRGB && transferFunction == d2.transferFunction && transferFunctionPower == d2.transferFunctionPower && + (primariesNameSet == d2.primariesNameSet && (primariesNameSet ? primariesNamed == d2.primariesNamed : primaries == d2.primaries)) && + masteringPrimaries == d2.masteringPrimaries && luminances == d2.luminances && masteringLuminances == d2.masteringLuminances && maxCLL == d2.maxCLL && + maxFALL == d2.maxFALL; } const SPCPRimaries& getPrimaries() const { @@ -249,9 +275,44 @@ namespace NColorManagement { default: return sdrRefLuminance >= 0 ? sdrRefLuminance : SDR_REF_LUMINANCE; } }; + }; + + class CImageDescription { + public: + static WP from(const SImageDescription& imageDescription); + static WP from(const uint imageDescriptionId); + + WP with(const SImageDescription::SPCLuminances& luminances) const; - uint32_t findId() const; - uint32_t getId() const; - uint32_t updateId(); + const SImageDescription& value() const; + uint id() const; + + WP getPrimaries() const; + + private: + CImageDescription(const SImageDescription& imageDescription, const uint imageDescriptionId); + uint m_id; + uint m_primariesId; + SImageDescription m_imageDescription; }; + + using PImageDescription = WP; + + static const auto DEFAULT_IMAGE_DESCRIPTION = CImageDescription::from(SImageDescription{}); + static const auto DEFAULT_HDR_IMAGE_DESCRIPTION = CImageDescription::from(SImageDescription{.transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ, + .primariesNameSet = true, + .primariesNamed = NColorManagement::CM_PRIMARIES_BT2020, + .primaries = NColorManagement::getPrimaries(NColorManagement::CM_PRIMARIES_BT2020), + .luminances = {.min = 0, .max = 10000, .reference = 203}}); + ; + static const auto SCRGB_IMAGE_DESCRIPTION = CImageDescription::from(SImageDescription{ + .windowsScRGB = true, + .transferFunction = NColorManagement::CM_TRANSFER_FUNCTION_EXT_LINEAR, + .primariesNameSet = true, + .primariesNamed = NColorManagement::CM_PRIMARIES_SRGB, + .primaries = NColorPrimaries::BT709, + .luminances = {.reference = 203}, + }); + ; + } \ No newline at end of file -- cgit v1.2.3