File indexing completed on 2024-11-10 04:57:27
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"