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 <ankit.k.nautiyal@intel.com>
diff --git a/libweston/compositor.c b/libweston/compositor.c
index ddce8f0..ad78eaa 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -479,6 +479,8 @@
state->buffer_viewport.changed = 0;
state->acquire_fence_fd = -1;
+
+ state->desired_protection = WESTON_HDCP_DISABLE;
}
static void
@@ -561,6 +563,8 @@
surface->acquire_fence_fd = -1;
+ surface->desired_protection = WESTON_HDCP_DISABLE;
+
return surface;
}
@@ -2528,6 +2532,7 @@
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 @@
/* 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 {
@@ -3329,6 +3351,16 @@
}
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 @@
/* 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 @@
&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_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;