mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2025-12-20 14:00:10 +01:00
compositor: Add an explicit latch point
Latch is the moment when the compositor considers updates for an upcoming redraw. Nothing that takes place after an output latches for repaint can change what will be repainted. This needs a more explicit treatment now that upcoming transactional protocols require things to happen immediately after the latch (ie: when it's too late to change the upcoming render). Add an explicit latch point, a signal to tap for testing, and some asserts to make sure nothing can violate the inevitability of the current render state. Note that currently latch is tied to repaint such that we only claim to have latched when a repaint will happen. In a future commit this will lead to forcing the repaint loop to fire without damage when the fifo protocol needs something to happen after a latch. This could be an area for future improvement. Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
parent
b700c7cbee
commit
e4be014f93
5 changed files with 53 additions and 0 deletions
|
|
@ -438,6 +438,7 @@ struct weston_output {
|
||||||
struct wl_event_source *idle_repaint_source;
|
struct wl_event_source *idle_repaint_source;
|
||||||
|
|
||||||
struct wl_signal frame_signal;
|
struct wl_signal frame_signal;
|
||||||
|
struct wl_signal post_latch_signal;
|
||||||
struct wl_signal destroy_signal; /**< sent when disabled */
|
struct wl_signal destroy_signal; /**< sent when disabled */
|
||||||
struct weston_coord_global move;
|
struct weston_coord_global move;
|
||||||
struct timespec frame_time; /* presentation timestamp */
|
struct timespec frame_time; /* presentation timestamp */
|
||||||
|
|
@ -1493,6 +1494,13 @@ struct weston_compositor {
|
||||||
uint32_t placeholder_color;
|
uint32_t placeholder_color;
|
||||||
|
|
||||||
bool no_xwm_decorations;
|
bool no_xwm_decorations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set the compositor has latched content updates for the
|
||||||
|
* upcoming repaint, and no more updates may be applied until after
|
||||||
|
* that repaint occurs.
|
||||||
|
*/
|
||||||
|
bool latched;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weston_solid_buffer_values {
|
struct weston_solid_buffer_values {
|
||||||
|
|
|
||||||
|
|
@ -3615,6 +3615,21 @@ output_assign_planes(struct weston_output *output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The "latch" point is the last possible instant before a repaint. After
|
||||||
|
* the latch, no more content updates can be applied by the compositor
|
||||||
|
* until after the scheduled repaint completes.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
weston_output_latch(struct weston_output *output)
|
||||||
|
{
|
||||||
|
struct weston_compositor *compositor = output->compositor;
|
||||||
|
|
||||||
|
assert(!compositor->latched);
|
||||||
|
compositor->latched = true;
|
||||||
|
|
||||||
|
wl_signal_emit(&output->post_latch_signal, output);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
weston_output_repaint(struct weston_output *output)
|
weston_output_repaint(struct weston_output *output)
|
||||||
{
|
{
|
||||||
|
|
@ -3628,6 +3643,8 @@ weston_output_repaint(struct weston_output *output)
|
||||||
uint32_t frame_time_msec;
|
uint32_t frame_time_msec;
|
||||||
enum weston_hdcp_protection highest_requested = WESTON_HDCP_DISABLE;
|
enum weston_hdcp_protection highest_requested = WESTON_HDCP_DISABLE;
|
||||||
|
|
||||||
|
weston_output_latch(output);
|
||||||
|
|
||||||
TL_POINT(ec, TLP_CORE_REPAINT_BEGIN, TLP_OUTPUT(output), TLP_END);
|
TL_POINT(ec, TLP_CORE_REPAINT_BEGIN, TLP_OUTPUT(output), TLP_END);
|
||||||
|
|
||||||
/* Rebuild the surface list and update surface transforms up front. */
|
/* Rebuild the surface list and update surface transforms up front. */
|
||||||
|
|
@ -3696,6 +3713,7 @@ weston_output_repaint(struct weston_output *output)
|
||||||
output_accumulate_damage(output);
|
output_accumulate_damage(output);
|
||||||
|
|
||||||
r = output->repaint(output);
|
r = output->repaint(output);
|
||||||
|
ec->latched = false;
|
||||||
|
|
||||||
output->repaint_needed = false;
|
output->repaint_needed = false;
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
|
|
@ -8115,6 +8133,7 @@ weston_output_enable(struct weston_output *output)
|
||||||
output->original_scale = output->current_scale;
|
output->original_scale = output->current_scale;
|
||||||
|
|
||||||
wl_signal_init(&output->frame_signal);
|
wl_signal_init(&output->frame_signal);
|
||||||
|
wl_signal_init(&output->post_latch_signal);
|
||||||
wl_signal_init(&output->destroy_signal);
|
wl_signal_init(&output->destroy_signal);
|
||||||
|
|
||||||
weston_output_transform_scale_init(output, output->transform,
|
weston_output_transform_scale_init(output, output->transform,
|
||||||
|
|
|
||||||
|
|
@ -272,6 +272,8 @@ weston_surface_apply_state(struct weston_surface *surface,
|
||||||
pixman_region32_t opaque;
|
pixman_region32_t opaque;
|
||||||
enum weston_surface_status status = state->status;
|
enum weston_surface_status status = state->status;
|
||||||
|
|
||||||
|
assert(!surface->compositor->latched);
|
||||||
|
|
||||||
surface->flow_id = state->flow_id;
|
surface->flow_id = state->flow_id;
|
||||||
state->flow_id = 0;
|
state->flow_id = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,8 @@
|
||||||
<enum name="breakpoint">
|
<enum name="breakpoint">
|
||||||
<entry name="post_repaint" value="0"
|
<entry name="post_repaint" value="0"
|
||||||
summary="after output repaint (filter type: wl_output)"/>
|
summary="after output repaint (filter type: wl_output)"/>
|
||||||
|
<entry name="post_latch" value="1"
|
||||||
|
summary="after output latch (filter type: wl_output)"/>
|
||||||
</enum>
|
</enum>
|
||||||
|
|
||||||
<request name="client_break">
|
<request name="client_break">
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ struct weston_test_output {
|
||||||
struct weston_test *test;
|
struct weston_test *test;
|
||||||
struct weston_output *output;
|
struct weston_output *output;
|
||||||
struct wl_listener repaint_listener;
|
struct wl_listener repaint_listener;
|
||||||
|
struct wl_listener post_latch_listener;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -138,6 +139,20 @@ output_repaint_listener(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
output_post_latch_listener(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct weston_test_output *to =
|
||||||
|
container_of(listener, struct weston_test_output,
|
||||||
|
post_latch_listener);
|
||||||
|
struct weston_head *head;
|
||||||
|
|
||||||
|
wl_list_for_each(head, &to->output->head_list, output_link) {
|
||||||
|
maybe_breakpoint(to->test, WESTON_TEST_BREAKPOINT_POST_LATCH,
|
||||||
|
head);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
output_created_listener(struct wl_listener *listener, void *data)
|
output_created_listener(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -149,8 +164,13 @@ output_created_listener(struct wl_listener *listener, void *data)
|
||||||
|
|
||||||
to->test = test;
|
to->test = test;
|
||||||
to->output = output;
|
to->output = output;
|
||||||
|
|
||||||
to->repaint_listener.notify = output_repaint_listener;
|
to->repaint_listener.notify = output_repaint_listener;
|
||||||
wl_signal_add(&output->frame_signal, &to->repaint_listener);
|
wl_signal_add(&output->frame_signal, &to->repaint_listener);
|
||||||
|
|
||||||
|
to->post_latch_listener.notify = output_post_latch_listener;
|
||||||
|
wl_signal_add(&output->post_latch_signal, &to->post_latch_listener);
|
||||||
|
|
||||||
wl_list_insert(&test->output_list, &to->link);
|
wl_list_insert(&test->output_list, &to->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,6 +188,7 @@ output_destroyed_listener(struct wl_listener *listener, void *data)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
wl_list_remove(&to->repaint_listener.link);
|
wl_list_remove(&to->repaint_listener.link);
|
||||||
|
wl_list_remove(&to->post_latch_listener.link);
|
||||||
wl_list_remove(&to->link);
|
wl_list_remove(&to->link);
|
||||||
free(to);
|
free(to);
|
||||||
}
|
}
|
||||||
|
|
@ -883,6 +904,7 @@ out_free:
|
||||||
|
|
||||||
wl_list_for_each_safe(to, tmp, &test->output_list, link) {
|
wl_list_for_each_safe(to, tmp, &test->output_list, link) {
|
||||||
wl_list_remove(&to->repaint_listener.link);
|
wl_list_remove(&to->repaint_listener.link);
|
||||||
|
wl_list_remove(&to->post_latch_listener.link);
|
||||||
wl_list_remove(&to->link);
|
wl_list_remove(&to->link);
|
||||||
free(to);
|
free(to);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue