This makes --icc-auto work on wayland. Closes #8151.
Unified · Split
| @@ -32,6 +32,7 @@ · 31 unmodified lines | |||
| 32 | #include "osdep/poll_wrapper.h" | 32 | #include "osdep/poll_wrapper.h" |
| 33 | #include "osdep/timer.h" | 33 | #include "osdep/timer.h" |
| 34 | #include "present_sync.h" | 34 | #include "present_sync.h" |
| 35 | #include "video/out/gpu/video.h" | ||
| 35 | #include "wayland_common.h" | 36 | #include "wayland_common.h" |
| 36 | #include "win_state.h" | 37 | #include "win_state.h" |
| 37 | 38 | ||
| @@ -252,6 +253,7 @@ static int spawn_cursor(struct vo_wayland_state *wl); · 214 unmodified lines | |||
| 252 | static void add_feedback(struct vo_wayland_feedback_pool *fback_pool, | 253 | static void add_feedback(struct vo_wayland_feedback_pool *fback_pool, |
| 253 | struct wp_presentation_feedback *fback); | 254 | struct wp_presentation_feedback *fback); |
| 254 | static void apply_keepaspect(struct vo_wayland_state *wl, int *width, int *height); | 255 | static void apply_keepaspect(struct vo_wayland_state *wl, int *width, int *height); |
| 256 | static void get_compositor_icc_file(struct vo_wayland_state *wl); | ||
| 255 | static void get_shape_device(struct vo_wayland_state *wl, struct vo_wayland_seat *s); | 257 | static void get_shape_device(struct vo_wayland_state *wl, struct vo_wayland_seat *s); |
| 256 | static void guess_focus(struct vo_wayland_state *wl); | 258 | static void guess_focus(struct vo_wayland_state *wl); |
| 257 | static void handle_key_input(struct vo_wayland_seat *s, uint32_t key, uint32_t state, bool no_emit); | 259 | static void handle_key_input(struct vo_wayland_seat *s, uint32_t key, uint32_t state, bool no_emit); |
| @@ -1403,7 +1405,7 @@ static void supported_feature(void *data, struct wp_color_manager_v1 *color_mana · 1145 unmodified lines | |||
| 1403 | switch (feature) { | 1405 | switch (feature) { |
| 1404 | case WP_COLOR_MANAGER_V1_FEATURE_ICC_V2_V4: | 1406 | case WP_COLOR_MANAGER_V1_FEATURE_ICC_V2_V4: |
| 1405 | MP_VERBOSE(wl, "Compositor supports ICC creator requests.\n"); | 1407 | MP_VERBOSE(wl, "Compositor supports ICC creator requests.\n"); |
| 1406 | wl->supports_icc = true; // TODO: actually implement | 1408 | wl->supports_icc = true; |
| 1407 | break; | 1409 | break; |
| 1408 | case WP_COLOR_MANAGER_V1_FEATURE_PARAMETRIC: | 1410 | case WP_COLOR_MANAGER_V1_FEATURE_PARAMETRIC: |
| 1409 | MP_VERBOSE(wl, "Compositor supports parametric image description creator.\n"); | 1411 | MP_VERBOSE(wl, "Compositor supports parametric image description creator.\n"); |
| @@ -1530,6 +1532,106 @@ static const struct wp_image_description_v1_listener image_description_listener · 120 unmodified lines | |||
| 1530 | image_description_failed, | 1532 | image_description_failed, |
| 1531 | image_description_ready, | 1533 | image_description_ready, |
| 1532 | }; | 1534 | }; |
| 1535 | |||
| 1536 | static void info_done(void *data, struct wp_image_description_info_v1 *image_description_info) | ||
| 1537 | { | ||
| 1538 | struct vo_wayland_state *wl = data; | ||
| 1539 | wp_image_description_info_v1_destroy(image_description_info); | ||
| 1540 | if (!wl->icc_file) | ||
| 1541 | MP_VERBOSE(wl, "No ICC profile retrieved from the compositor.\n"); | ||
| 1542 | } | ||
| 1543 | |||
| 1544 | static void info_icc_file(void *data, struct wp_image_description_info_v1 *image_description_info, | ||
| 1545 | int32_t icc, uint32_t icc_size) | ||
| 1546 | { | ||
| 1547 | struct vo_wayland_state *wl = data; | ||
| 1548 | if (wl->icc_size) { | ||
| 1549 | munmap(wl->icc_file, wl->icc_size); | ||
| 1550 | wl->icc_file = NULL; | ||
| 1551 | wl->icc_size = 0; | ||
| 1552 | } | ||
| 1553 | |||
| 1554 | void *icc_file = mmap(NULL, icc_size, PROT_READ, MAP_PRIVATE, icc, 0); | ||
| 1555 | close(icc); | ||
| 1556 | |||
| 1557 | if (icc_file != MAP_FAILED) { | ||
| 1558 | wl->icc_file = icc_file; | ||
| 1559 | wl->icc_size = icc_size; | ||
| 1560 | } | ||
| 1561 | wl->pending_vo_events |= VO_EVENT_ICC_PROFILE_CHANGED; | ||
| 1562 | } | ||
| 1563 | |||
| 1564 | static void info_primaries(void *data, struct wp_image_description_info_v1 *image_description_info, | ||
| 1565 | int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y, int32_t b_x, int32_t b_y, | ||
| 1566 | int32_t w_x, int32_t w_y) | ||
| 1567 | { | ||
| 1568 | } | ||
| 1569 | |||
| 1570 | static void info_primaries_named(void *data, struct wp_image_description_info_v1 *image_description_info, | ||
| 1571 | uint32_t primaries) | ||
| 1572 | { | ||
| 1573 | } | ||
| 1574 | |||
| 1575 | static void info_tf_power(void *data, struct wp_image_description_info_v1 *image_description_info, | ||
| 1576 | uint32_t eexp) | ||
| 1577 | { | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | static void info_tf_named(void *data, struct wp_image_description_info_v1 *image_description_info, | ||
| 1581 | uint32_t tf) | ||
| 1582 | { | ||
| 1583 | } | ||
| 1584 | |||
| 1585 | static void info_luminances(void *data, struct wp_image_description_info_v1 *image_description_info, | ||
| 1586 | uint32_t min_lum, uint32_t max_lum, uint32_t reference_lum) | ||
| 1587 | { | ||
| 1588 | } | ||
| 1589 | |||
| 1590 | static void info_target_primaries(void *data, struct wp_image_description_info_v1 *image_description_info, | ||
| 1591 | int32_t r_x, int32_t r_y, int32_t g_x, int32_t g_y, int32_t b_x, int32_t b_y, | ||
| 1592 | int32_t w_x, int32_t w_y) | ||
| 1593 | { | ||
| 1594 | } | ||
| 1595 | |||
| 1596 | static void info_target_luminance(void *data, struct wp_image_description_info_v1 *image_description_info, | ||
| 1597 | uint32_t min_lum, uint32_t max_lum) | ||
| 1598 | { | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | static void info_target_max_cll(void *data, struct wp_image_description_info_v1 *image_description_info, | ||
| 1602 | uint32_t max_cll) | ||
| 1603 | { | ||
| 1604 | } | ||
| 1605 | |||
| 1606 | static void info_target_max_fall(void *data, struct wp_image_description_info_v1 *image_description_info, | ||
| 1607 | uint32_t max_fall) | ||
| 1608 | { | ||
| 1609 | } | ||
| 1610 | |||
| 1611 | static const struct wp_image_description_info_v1_listener image_description_info_listener = { | ||
| 1612 | info_done, | ||
| 1613 | info_icc_file, | ||
| 1614 | info_primaries, | ||
| 1615 | info_primaries_named, | ||
| 1616 | info_tf_power, | ||
| 1617 | info_tf_named, | ||
| 1618 | info_luminances, | ||
| 1619 | info_target_primaries, | ||
| 1620 | info_target_luminance, | ||
| 1621 | info_target_max_cll, | ||
| 1622 | info_target_max_fall, | ||
| 1623 | }; | ||
| 1624 | |||
| 1625 | static void preferred_changed(void *data, struct wp_color_management_surface_feedback_v1 *color_surface_feedback, | ||
| 1626 | uint32_t identity) | ||
| 1627 | { | ||
| 1628 | struct vo_wayland_state *wl = data; | ||
| 1629 | get_compositor_icc_file(wl); | ||
| 1630 | } | ||
| 1631 | |||
| 1632 | static const struct wp_color_management_surface_feedback_v1_listener surface_feedback_listener = { | ||
| 1633 | preferred_changed, | ||
| 1634 | }; | ||
| 1533 | #endif | 1635 | #endif |
| 1534 | 1636 | ||
| 1535 | static const char *zxdg_decoration_mode_to_str(const uint32_t mode) | 1637 | static const char *zxdg_decoration_mode_to_str(const uint32_t mode) |
| @@ -2219,6 +2321,18 @@ static int get_mods(struct vo_wayland_seat *s) · 683 unmodified lines | |||
| 2219 | return modifiers; | 2321 | return modifiers; |
| 2220 | } | 2322 | } |
| 2221 | 2323 | ||
| 2324 | static void get_compositor_icc_file(struct vo_wayland_state *wl) | ||
| 2325 | { | ||
| 2326 | #if HAVE_WAYLAND_PROTOCOLS_1_41 | ||
| 2327 | struct wp_image_description_v1 *image_description = | ||
| 2328 | wp_color_management_surface_feedback_v1_get_preferred(wl->color_surface_feedback); | ||
| 2329 | struct wp_image_description_info_v1 *description_info = | ||
| 2330 | wp_image_description_v1_get_information(image_description); | ||
| 2331 | wp_image_description_info_v1_add_listener(description_info, &image_description_info_listener, wl); | ||
| 2332 | wp_image_description_v1_destroy(image_description); | ||
| 2333 | #endif | ||
| 2334 | } | ||
| 2335 | |||
| 2222 | static void get_shape_device(struct vo_wayland_state *wl, struct vo_wayland_seat *s) | 2336 | static void get_shape_device(struct vo_wayland_state *wl, struct vo_wayland_seat *s) |
| 2223 | { | 2337 | { |
| 2224 | #if HAVE_WAYLAND_PROTOCOLS_1_32 | 2338 | #if HAVE_WAYLAND_PROTOCOLS_1_32 |
| @@ -2991,6 +3105,15 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg) · 766 unmodified lines | |||
| 2991 | *(char ***)arg = get_displays_spanned(wl); | 3105 | *(char ***)arg = get_displays_spanned(wl); |
| 2992 | return VO_TRUE; | 3106 | return VO_TRUE; |
| 2993 | } | 3107 | } |
| 3108 | case VOCTRL_GET_ICC_PROFILE: { | ||
| 3109 | if (!wl->supports_icc) | ||
| 3110 | MP_WARN(wl, "Compositor does not support ICC profiles!\n"); | ||
| 3111 | if (!wl->icc_file) | ||
| 3112 | return VO_FALSE; | ||
| 3113 | MP_VERBOSE(wl, "Retrieving ICC profile from compositor.\n"); | ||
| 3114 | *(bstr *)arg = bstrdup(NULL, (bstr){wl->icc_file, wl->icc_size}); | ||
| 3115 | return VO_TRUE; | ||
| 3116 | } | ||
| 2994 | case VOCTRL_GET_UNFS_WINDOW_SIZE: { | 3117 | case VOCTRL_GET_UNFS_WINDOW_SIZE: { |
| 2995 | int *s = arg; | 3118 | int *s = arg; |
| 2996 | if (wl->opts->window_maximized || wl->tiled) { | 3119 | if (wl->opts->window_maximized || wl->tiled) { |
| @@ -3292,14 +3415,29 @@ bool vo_wayland_init(struct vo *vo) · 295 unmodified lines | |||
| 3292 | wl_display_roundtrip(wl->display); | 3415 | wl_display_roundtrip(wl->display); |
| 3293 | 3416 | ||
| 3294 | #if HAVE_WAYLAND_PROTOCOLS_1_41 | 3417 | #if HAVE_WAYLAND_PROTOCOLS_1_41 |
| 3295 | // Only bind to vo_dmabuf_wayland for now to avoid conflicting with graphics drivers | 3418 | // Only bind color surface to vo_dmabuf_wayland for now to avoid conflicting with graphics drivers |
| 3296 | if (wl->color_manager && wl->supports_parametric && !strcmp(wl->vo->driver->name, "dmabuf-wayland")) { | 3419 | if (wl->color_manager && wl->supports_parametric && !strcmp(wl->vo->driver->name, "dmabuf-wayland")) |
| 3297 | wl->color_surface = wp_color_manager_v1_get_surface(wl->color_manager, wl->callback_surface); | 3420 | wl->color_surface = wp_color_manager_v1_get_surface(wl->color_manager, wl->callback_surface); |
| 3298 | } else { | 3421 | |
| 3299 | MP_VERBOSE(wl, "Compositor does not support parametric image descriptions!\n"); | 3422 | if (wl->color_manager && wl->supports_icc) { |
| 3423 | wl->color_surface_feedback = wp_color_manager_v1_get_surface_feedback(wl->color_manager, wl->callback_surface); | ||
| 3424 | wp_color_management_surface_feedback_v1_add_listener(wl->color_surface_feedback, &surface_feedback_listener, wl); | ||
| 3300 | } | 3425 | } |
| 3301 | #endif | 3426 | #endif |
| 3302 | 3427 | ||
| 3428 | if (!wl->supports_parametric) | ||
| 3429 | MP_VERBOSE(wl, "Compositor does not support parametric image descriptions!\n"); | ||
| 3430 | |||
| 3431 | struct gl_video_opts *gl_opts = mp_get_config_group(NULL, vo->global, &gl_video_conf); | ||
| 3432 | if (wl->supports_icc) { | ||
| 3433 | // dumb workaround for avoiding -Wunused-function | ||
| 3434 | get_compositor_icc_file(wl); | ||
| 3435 | } else { | ||
| 3436 | int msg_level = gl_opts->icc_opts->profile_auto ? MSGL_WARN : MSGL_V; | ||
| 3437 | mp_msg(wl->log, msg_level, "Compositor does not support ICC profiles!\n"); | ||
| 3438 | } | ||
| 3439 | talloc_free(gl_opts); | ||
| 3440 | |||
| 3303 | return true; | 3441 | return true; |
| 3304 | 3442 | ||
| 3305 | err: | 3443 | err: |
| @@ -3399,6 +3537,9 @@ void vo_wayland_uninit(struct vo *vo) · 93 unmodified lines | |||
| 3399 | 3537 | ||
| 3400 | if (wl->color_surface) | 3538 | if (wl->color_surface) |
| 3401 | wp_color_management_surface_v1_destroy(wl->color_surface); | 3539 | wp_color_management_surface_v1_destroy(wl->color_surface); |
| 3540 | |||
| 3541 | if (wl->color_surface_feedback) | ||
| 3542 | wp_color_management_surface_feedback_v1_destroy(wl->color_surface_feedback); | ||
| 3402 | #endif | 3543 | #endif |
| 3403 | 3544 | ||
| 3404 | if (wl->content_type) | 3545 | if (wl->content_type) |
| @@ -92,6 +92,8 @@ struct vo_wayland_state { · 91 unmodified lines | |||
| 92 | /* color-management */ | 92 | /* color-management */ |
| 93 | struct wp_color_manager_v1 *color_manager; | 93 | struct wp_color_manager_v1 *color_manager; |
| 94 | struct wp_color_management_surface_v1 *color_surface; | 94 | struct wp_color_management_surface_v1 *color_surface; |
| 95 | struct wp_color_management_surface_feedback_v1 *color_surface_feedback; | ||
| 96 | struct wp_image_description_creator_icc_v1 *icc_creator; | ||
| 95 | struct mp_image_params target_params; | 97 | struct mp_image_params target_params; |
| 96 | bool supports_icc; | 98 | bool supports_icc; |
| 97 | bool supports_parametric; | 99 | bool supports_parametric; |
| @@ -101,6 +103,8 @@ struct vo_wayland_state { · 3 unmodified lines | |||
| 101 | bool supports_display_primaries; | 103 | bool supports_display_primaries; |
| 102 | int primaries_map[PL_COLOR_PRIM_COUNT]; | 104 | int primaries_map[PL_COLOR_PRIM_COUNT]; |
| 103 | int transfer_map[PL_COLOR_TRC_COUNT]; | 105 | int transfer_map[PL_COLOR_TRC_COUNT]; |
| 106 | void *icc_file; | ||
| 107 | uint32_t icc_size; | ||
| 104 | 108 | ||
| 105 | /* content-type */ | 109 | /* content-type */ |
| 106 | struct wp_content_type_manager_v1 *content_type_manager; | 110 | struct wp_content_type_manager_v1 *content_type_manager; |