From 4b6e73d617676af8ec14c410fe396b4bf49cb16b Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Tue, 26 Mar 2019 13:37:12 +0530 Subject: [PATCH] libweston: Add support to set content-protection for a weston_surface The protection requested for a given surface, must reach through the weston_surface::pending_state, in the commit-cycle for the weston_surface, so that it gets updated in the next commit. As some protection is requested for a given weston_surface, it means protection must be set for each of the outputs which show the surface. While setting the protection of a weston_output, care must be taken so as to avoid, degrading the protection of another surfaces, enjoying the protection. For this purpose, all the weston_surfaces that are shown on a weston_output are checked for their desired protection. The highest of all such desired protections must be set for the weston_output to avoid degrading of existing protected surfaces. A surface requesting protection for a lower content-type can still be provided protection for a higher type but the converse cannot be allowed. This patch adds support to set content-protection for a suface, which inturn sets the content-protection for each of the outputs on which it is shown, provided, none of the existing surface's protection request is downgraded. Signed-off-by: Ankit Nautiyal --- include/libweston/libweston.h | 5 +++++ libweston/compositor.c | 37 ++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index b49e453b..620b66c9 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -1439,6 +1439,9 @@ struct weston_surface_state { /* zwp_surface_synchronization_v1.get_release */ struct weston_buffer_release_reference buffer_release_ref; + + /* weston_protected_surface.set_type */ + enum weston_hdcp_protection desired_protection; }; struct weston_surface_activation_data { @@ -1568,6 +1571,8 @@ struct weston_surface { struct wl_resource *synchronization_resource; int acquire_fence_fd; struct weston_buffer_release_reference buffer_release_ref; + + enum weston_hdcp_protection desired_protection; }; struct weston_subsurface { diff --git a/libweston/compositor.c b/libweston/compositor.c index ddce8f0f..ad78eaab 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -479,6 +479,8 @@ weston_surface_state_init(struct weston_surface_state *state) state->buffer_viewport.changed = 0; state->acquire_fence_fd = -1; + + state->desired_protection = WESTON_HDCP_DISABLE; } static void @@ -561,6 +563,8 @@ weston_surface_create(struct weston_compositor *compositor) surface->acquire_fence_fd = -1; + surface->desired_protection = WESTON_HDCP_DISABLE; + return surface; } @@ -2528,6 +2532,7 @@ weston_output_repaint(struct weston_output *output, void *repaint_data) pixman_region32_t output_damage; int r; uint32_t frame_time_msec; + enum weston_hdcp_protection highest_requested = WESTON_HDCP_DISABLE; if (output->destroying) return 0; @@ -2537,6 +2542,23 @@ weston_output_repaint(struct weston_output *output, void *repaint_data) /* Rebuild the surface list and update surface transforms up front. */ weston_compositor_build_view_list(ec); + /* Find the highest protection desired for an output */ + wl_list_for_each(ev, &ec->view_list, link) { + if (ev->surface->output_mask & (1u << output->id)) { + /* + * The desired_protection of the output should be the + * maximum of the desired_protection of the surfaces, + * that are displayed on that output, to avoid + * reducing the protection for existing surfaces. + */ + if (ev->surface->desired_protection > highest_requested) + highest_requested = + ev->surface->desired_protection; + } + } + + output->desired_protection = highest_requested; + if (output->assign_planes && !output->disable_planes) { output->assign_planes(output, repaint_data); } else { @@ -3328,6 +3350,16 @@ apply_damage_buffer(pixman_region32_t *dest, pixman_region32_clear(&state->damage_buffer); } +static void +weston_surface_set_desired_protection(struct weston_surface *surface, + enum weston_hdcp_protection protection) +{ + if (surface->desired_protection == protection) + return; + surface->desired_protection = protection; + weston_surface_damage(surface); +} + static void weston_surface_commit_state(struct weston_surface *surface, struct weston_surface_state *state) @@ -3349,7 +3381,6 @@ weston_surface_commit_state(struct weston_surface *surface, /* zwp_surface_synchronization_v1.get_release */ weston_buffer_release_move(&surface->buffer_release_ref, &state->buffer_release_ref); - weston_surface_attach(surface, state->buffer); } weston_surface_state_set_buffer(state, NULL); @@ -3419,6 +3450,9 @@ weston_surface_commit_state(struct weston_surface *surface, &state->feedback_list); wl_list_init(&state->feedback_list); + /* weston_protected_surface.set_type */ + weston_surface_set_desired_protection(surface, state->desired_protection); + wl_signal_emit(&surface->commit_signal, surface); } @@ -3718,6 +3752,7 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub) weston_buffer_release_move(&sub->cached.buffer_release_ref, &surface->pending.buffer_release_ref); } + sub->cached.desired_protection = surface->pending.desired_protection; assert(surface->pending.acquire_fence_fd == -1); assert(surface->pending.buffer_release_ref.buffer_release == NULL); sub->cached.sx += surface->pending.sx;