diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 66df2914e92..5a343e4c7ce 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -402,6 +402,10 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND) generate_protocol_bindings( "${WAYLAND_PROTOCOLS_DIR}/stable/viewporter/viewporter.xml" ) + # Color management (HDR properties) + generate_protocol_bindings( + "${WAYLAND_PROTOCOLS_DIR}/staging/color-management/color-management-v1.xml" + ) # Pointer-constraints. generate_protocol_bindings( "${WAYLAND_PROTOCOLS_DIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml" diff --git a/intern/ghost/intern/GHOST_SystemWayland.cc b/intern/ghost/intern/GHOST_SystemWayland.cc index a50d2aa17c2..bee5d71f573 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cc +++ b/intern/ghost/intern/GHOST_SystemWayland.cc @@ -59,6 +59,7 @@ #include /* Generated by `wayland-scanner`. */ +#include #include #include #include @@ -1441,6 +1442,7 @@ struct GWL_Display { zwp_primary_selection_device_manager_v1 *primary_selection_device_manager = nullptr; wp_fractional_scale_manager_v1 *fractional_scale_manager = nullptr; wp_viewporter *viewporter = nullptr; + wp_color_manager_v1 *color_manager = nullptr; zwp_pointer_constraints_v1 *pointer_constraints = nullptr; zwp_pointer_gestures_v1 *pointer_gestures = nullptr; #ifdef WITH_INPUT_IME @@ -6621,6 +6623,26 @@ static void gwl_registry_wl_output_remove(GWL_Display *display, delete output; } +/* #GWL_Display.wp_color_manager */ + +static void gwl_registry_wp_color_manager_add(GWL_Display *display, + const GWL_RegisteryAdd_Params ¶ms) +{ + const uint version = GWL_IFACE_VERSION_CLAMP(params.version, 1u, 1u); + + display->wp.color_manager = static_cast(wl_registry_bind( + display->wl.registry, params.name, &wp_color_manager_v1_interface, version)); + gwl_registry_entry_add(display, params, nullptr); +} +static void gwl_registry_wp_color_manager_remove(GWL_Display *display, + void * /*user_data*/, + const bool /*on_exit*/) +{ + wp_color_manager_v1 **value_p = &display->wp.color_manager; + wp_color_manager_v1_destroy(*value_p); + *value_p = nullptr; +} + /* #GWL_Display.seats */ static void gwl_registry_wl_seat_add(GWL_Display *display, const GWL_RegisteryAdd_Params ¶ms) @@ -7177,6 +7199,12 @@ static const GWL_RegistryHandler gwl_registry_handlers[] = { /*update_fn*/ gwl_registry_wl_output_update, /*remove_fn*/ gwl_registry_wl_output_remove, }, + { + /*interface_p*/ &wp_color_manager_v1_interface.name, + /*add_fn*/ gwl_registry_wp_color_manager_add, + /*update_fn*/ nullptr, + /*remove_fn*/ gwl_registry_wp_color_manager_remove, + }, /* Seats. * Keep the seat near the end to ensure other types are created first. * as the seat creates data based on other interfaces. */ @@ -9026,6 +9054,10 @@ wp_viewporter *GHOST_SystemWayland::wp_viewporter_get() { return display_->wp.viewporter; } +wp_color_manager_v1 *GHOST_SystemWayland::wp_color_manager_get() +{ + return display_->wp.color_manager; +} zwp_pointer_gestures_v1 *GHOST_SystemWayland::wp_pointer_gestures_get() { diff --git a/intern/ghost/intern/GHOST_SystemWayland.hh b/intern/ghost/intern/GHOST_SystemWayland.hh index e1bba3a8c50..d40dbdfa6ed 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.hh +++ b/intern/ghost/intern/GHOST_SystemWayland.hh @@ -264,6 +264,7 @@ class GHOST_SystemWayland : public GHOST_System { struct zwp_pointer_gestures_v1 *wp_pointer_gestures_get(); struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager_get(); struct wp_viewporter *wp_viewporter_get(); + struct wp_color_manager_v1 *wp_color_manager_get(); #ifdef WITH_GHOST_WAYLAND_LIBDECOR libdecor *libdecor_context_get(); diff --git a/intern/ghost/intern/GHOST_WindowWayland.cc b/intern/ghost/intern/GHOST_WindowWayland.cc index 2f7eca327e3..d8dba322baa 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cc +++ b/intern/ghost/intern/GHOST_WindowWayland.cc @@ -41,6 +41,7 @@ #endif /* Generated by `wayland-scanner`. */ +#include #include #include #include @@ -442,6 +443,7 @@ struct GWL_Window { * and ignore updated scale based on #wl_surface_listener::enter & exit events. */ wp_fractional_scale_v1 *fractional_scale_handle = nullptr; + wp_color_management_surface_v1 *color_management_surface = nullptr; } wp; /** XDG native types. */ @@ -1819,6 +1821,29 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, wl_surface_add_listener(window_->wl.surface, &wl_surface_listener, window_); + /* Color management */ + wp_color_manager_v1 *color_manager = system->wp_color_manager_get(); + if (color_manager) { + window_->wp.color_management_surface = wp_color_manager_v1_get_surface(color_manager, + window_->wl.surface); + + wp_image_description_creator_params_v1 *image_creator_params = + wp_color_manager_v1_create_parametric_creator(color_manager); + wp_image_description_creator_params_v1_set_tf_named( + image_creator_params, WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_SRGB); + wp_image_description_creator_params_v1_set_primaries_named(image_creator_params, + WP_COLOR_MANAGER_V1_PRIMARIES_SRGB); + + wp_image_description_v1 *image_description = wp_image_description_creator_params_v1_create( + image_creator_params); + + wp_color_management_surface_v1_set_image_description( + window_->wp.color_management_surface, + image_description, + WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL); + wp_image_description_v1_destroy(image_description); + } + wp_fractional_scale_manager_v1 *fractional_scale_manager = system->wp_fractional_scale_manager_get(); if (fractional_scale_manager) { @@ -2026,7 +2051,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, window_->backend.vulkan_window_info = new GHOST_ContextVK_WindowInfo; window_->backend.vulkan_window_info->size[0] = window_->frame.size[0]; window_->backend.vulkan_window_info->size[1] = window_->frame.size[1]; - window_->backend.vulkan_window_info->is_color_managed = true; + window_->backend.vulkan_window_info->is_color_managed = color_manager != nullptr; } #endif @@ -2161,6 +2186,11 @@ GHOST_WindowWayland::~GHOST_WindowWayland() window_->wp.viewport = nullptr; } + if (window_->wp.color_management_surface) { + wp_color_management_surface_v1_destroy(window_->wp.color_management_surface); + window_->wp.color_management_surface = nullptr; + } + #ifdef WITH_GHOST_WAYLAND_LIBDECOR if (use_libdecor) { gwl_libdecor_window_destroy(window_->libdecor);