File indexing completed on 2024-05-12 05:32:21

0001 /*
0002     SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #include "frog_colormanagement_v1.h"
0007 #include "display.h"
0008 #include "surface.h"
0009 #include "surface_p.h"
0010 
0011 namespace KWin
0012 {
0013 
0014 static constexpr uint32_t s_version = 1;
0015 
0016 FrogColorManagementV1::FrogColorManagementV1(Display *display, QObject *parent)
0017     : QObject(parent)
0018     , QtWaylandServer::frog_color_management_factory_v1(*display, s_version)
0019 {
0020 }
0021 
0022 FrogColorManagementV1::~FrogColorManagementV1()
0023 {
0024 }
0025 
0026 void FrogColorManagementV1::frog_color_management_factory_v1_get_color_managed_surface(Resource *resource, wl_resource *surface, uint32_t callback)
0027 {
0028     SurfaceInterface *surf = SurfaceInterface::get(surface);
0029     SurfaceInterfacePrivate::get(surf)->frogColorManagement = new FrogColorManagementSurfaceV1(surf, resource->client(), callback);
0030 }
0031 
0032 void FrogColorManagementV1::frog_color_management_factory_v1_destroy(Resource *resource)
0033 {
0034     wl_resource_destroy(resource->handle);
0035 }
0036 
0037 FrogColorManagementSurfaceV1::FrogColorManagementSurfaceV1(SurfaceInterface *surface, wl_client *client, uint32_t id)
0038     : QtWaylandServer::frog_color_managed_surface(client, id, s_version)
0039     , m_surface(surface)
0040 {
0041 }
0042 
0043 FrogColorManagementSurfaceV1::~FrogColorManagementSurfaceV1()
0044 {
0045     if (m_surface) {
0046         const auto priv = SurfaceInterfacePrivate::get(m_surface);
0047         priv->pending->colorDescription = ColorDescription::sRGB;
0048         priv->pending->colorDescriptionIsSet = true;
0049         priv->frogColorManagement = nullptr;
0050     }
0051 }
0052 
0053 static QtWaylandServer::frog_color_managed_surface::transfer_function kwinToFrogTransferFunction(NamedTransferFunction tf)
0054 {
0055     switch (tf) {
0056     case NamedTransferFunction::sRGB:
0057         return QtWaylandServer::frog_color_managed_surface::transfer_function_srgb;
0058     case NamedTransferFunction::gamma22:
0059         return QtWaylandServer::frog_color_managed_surface::transfer_function_gamma_22;
0060     case NamedTransferFunction::PerceptualQuantizer:
0061         return QtWaylandServer::frog_color_managed_surface::transfer_function_st2084_pq;
0062     case NamedTransferFunction::scRGB:
0063         return QtWaylandServer::frog_color_managed_surface::transfer_function_scrgb_linear;
0064     case NamedTransferFunction::linear:
0065         return QtWaylandServer::frog_color_managed_surface::transfer_function_scrgb_linear;
0066     }
0067     return QtWaylandServer::frog_color_managed_surface::transfer_function_undefined;
0068 }
0069 
0070 uint16_t encodePrimary(float primary)
0071 {
0072     return uint16_t(std::clamp<float>(std::round(primary / 0.00002), 0, 0xC350));
0073 }
0074 
0075 void FrogColorManagementSurfaceV1::setPreferredColorDescription(const ColorDescription &colorDescription)
0076 {
0077     const auto &color = colorDescription.colorimetry();
0078     send_preferred_metadata(kwinToFrogTransferFunction(colorDescription.transferFunction()),
0079                             encodePrimary(color.red().x()), encodePrimary(color.red().y()),
0080                             encodePrimary(color.green().x()), encodePrimary(color.green().y()),
0081                             encodePrimary(color.blue().x()), encodePrimary(color.blue().y()),
0082                             encodePrimary(color.white().x()), encodePrimary(color.white().y()),
0083                             std::round(colorDescription.maxHdrHighlightBrightness()),
0084                             std::round(colorDescription.minHdrBrightness() / 0.0001),
0085                             std::round(colorDescription.maxFrameAverageBrightness()));
0086 }
0087 
0088 void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_known_transfer_function(Resource *resource, uint32_t transfer_function)
0089 {
0090     switch (transfer_function) {
0091     case transfer_function_undefined:
0092     case transfer_function_srgb:
0093     case transfer_function_gamma_22:
0094         m_transferFunction = NamedTransferFunction::gamma22;
0095         break;
0096     case transfer_function_st2084_pq:
0097         m_transferFunction = NamedTransferFunction::PerceptualQuantizer;
0098         break;
0099     case transfer_function_scrgb_linear:
0100         m_transferFunction = NamedTransferFunction::scRGB;
0101         break;
0102     }
0103     updateColorDescription();
0104 }
0105 
0106 void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_known_container_color_volume(Resource *resource, uint32_t primaries)
0107 {
0108     switch (primaries) {
0109     case primaries_undefined:
0110     case primaries_rec709:
0111         m_colorimetry = NamedColorimetry::BT709;
0112         break;
0113     case primaries_rec2020:
0114         m_colorimetry = NamedColorimetry::BT2020;
0115         break;
0116     }
0117     updateColorDescription();
0118 }
0119 
0120 void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_render_intent(Resource *resource, uint32_t render_intent)
0121 {
0122     // there's only perceptual right now, so this can be ignored
0123 }
0124 
0125 void FrogColorManagementSurfaceV1::frog_color_managed_surface_set_hdr_metadata(Resource *resource,
0126                                                                                uint32_t mastering_display_primary_red_x, uint32_t mastering_display_primary_red_y,
0127                                                                                uint32_t mastering_display_primary_green_x, uint32_t mastering_display_primary_green_y,
0128                                                                                uint32_t mastering_display_primary_blue_x, uint32_t mastering_display_primary_blue_y,
0129                                                                                uint32_t mastering_white_point_x, uint32_t mastering_white_point_y,
0130                                                                                uint32_t max_display_mastering_luminance, uint32_t min_display_mastering_luminance,
0131                                                                                uint32_t max_cll, uint32_t max_fall)
0132 {
0133     m_maxPeakBrightness = max_cll;
0134     m_maxFrameAverageBrightness = max_fall;
0135     updateColorDescription();
0136 }
0137 
0138 void FrogColorManagementSurfaceV1::frog_color_managed_surface_destroy(Resource *resource)
0139 {
0140     wl_resource_destroy(resource->handle);
0141 }
0142 
0143 void FrogColorManagementSurfaceV1::frog_color_managed_surface_destroy_resource(Resource *resource)
0144 {
0145     delete this;
0146 }
0147 
0148 void FrogColorManagementSurfaceV1::updateColorDescription()
0149 {
0150     if (m_surface) {
0151         // TODO make brightness values optional in ColorDescription
0152         SurfaceInterfacePrivate *priv = SurfaceInterfacePrivate::get(m_surface);
0153         priv->pending->colorDescription = ColorDescription(m_colorimetry, m_transferFunction, 0, 0, m_maxFrameAverageBrightness, m_maxPeakBrightness);
0154         priv->pending->colorDescriptionIsSet = true;
0155     }
0156 }
0157 
0158 }
0159 
0160 #include "moc_frog_colormanagement_v1.cpp"