[PATCH weston v2 08/11] Change boolean repaint_scheduled to tristate enum

Daniel Stone daniels at collabora.com
Wed Mar 1 11:34:07 UTC 2017


repaint_scheduled is actually cleverly a tristate. There are three
possible conditions for the repaint loop to be in at any time:
  - loop idle; no repaint will occur until specifically requested, which
    may be never (repaint_scheduled == 0)
  - repaint scheduled: the compositor has definitively scheduled a
    repaint request for this output, which will occur in fixed time
  - awaiting repaint completion: the backend has not yet signaled
    completion of the last repaint request, and the compositor will not
    schedule another until it does so

The last two conditions were previously conflated as
repaint_scheduled == 1, but break them out into separate conditions to
aid clarity, backed up by some asserts.

I would like to further disambiguate between awaiting completion of
start_repaint_loop() and awaiting completion of repaint(), but that
requires more surgery to weston_output_finish_frame() and the backends
than seems currently appropriate.

Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 libweston/compositor.c | 20 +++++++++++++++++---
 libweston/compositor.h |  9 ++++++++-
 2 files changed, 25 insertions(+), 4 deletions(-)

v2: New in this revision. Required by change to avoid normalising
    next_repaint to uint32_t msec in global repaint timer.

diff --git a/libweston/compositor.c b/libweston/compositor.c
index 7f3532f..4aa30da 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -2311,6 +2311,8 @@ weston_output_repaint(struct weston_output *output)
 	pixman_region32_fini(&output_damage);
 
 	output->repaint_needed = false;
+	if (r == 0)
+		output->repaint_status = REPAINT_AWAITING_COMPLETION;
 
 	weston_compositor_repick(ec);
 
@@ -2332,7 +2334,7 @@ weston_output_repaint(struct weston_output *output)
 static void
 weston_output_schedule_repaint_reset(struct weston_output *output)
 {
-	output->repaint_scheduled = 0;
+	output->repaint_status = REPAINT_NOT_SCHEDULED;
 	TL_POINT("core_repaint_exit_loop", TLP_OUTPUT(output), TLP_END);
 }
 
@@ -2343,6 +2345,8 @@ output_repaint_timer_handler(void *data)
 	struct weston_compositor *compositor = output->compositor;
 	int ret;
 
+	assert(output->repaint_status == REPAINT_SCHEDULED);
+
 	/* If we're sleeping, drop the repaint machinery entirely; we will
 	 * explicitly repaint all outputs when we come back. */
 	if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
@@ -2383,6 +2387,7 @@ weston_output_finish_frame(struct weston_output *output,
 	TL_POINT("core_repaint_finished", TLP_OUTPUT(output),
 		 TLP_VBLANK(stamp), TLP_END);
 
+	assert(output->repaint_status == REPAINT_AWAITING_COMPLETION);
 	assert(stamp || (presented_flags & WP_PRESENTATION_FEEDBACK_INVALID));
 
 	/* If we haven't been supplied any timestamp at all, we don't have a
@@ -2424,6 +2429,8 @@ weston_output_finish_frame(struct weston_output *output,
 		msec_rel += refresh_nsec / 1000000;
 
 out:
+	output->repaint_status = REPAINT_SCHEDULED;
+
 	if (msec_rel < 1)
 		output_repaint_timer_handler(output);
 	else
@@ -2435,6 +2442,8 @@ idle_repaint(void *data)
 {
 	struct weston_output *output = data;
 
+	assert(output->repaint_status == REPAINT_SCHEDULED);
+	output->repaint_status = REPAINT_AWAITING_COMPLETION;
 	output->start_repaint_loop(output);
 }
 
@@ -2550,11 +2559,16 @@ weston_output_schedule_repaint(struct weston_output *output)
 
 	loop = wl_display_get_event_loop(compositor->wl_display);
 	output->repaint_needed = true;
-	if (output->repaint_scheduled)
+
+	/* If we already have a repaint scheduled for our idle handler,
+	 * no need to set it again. If the repaint has been called but
+	 * not finished, then weston_output_finish_frame() will notice
+	 * that a repaint is needed and schedule one. */
+	if (output->repaint_status != REPAINT_NOT_SCHEDULED)
 		return;
 
 	wl_event_loop_add_idle(loop, idle_repaint, output);
-	output->repaint_scheduled = 1;
+	output->repaint_status = REPAINT_SCHEDULED;
 	TL_POINT("core_repaint_enter_loop", TLP_OUTPUT(output), TLP_END);
 }
 
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 7d6e1c9..06a0ff5 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -174,7 +174,14 @@ struct weston_output {
 	/** True if damage has occurred since the last repaint for this output;
 	 *  if set, a repaint will eventually occur. */
 	bool repaint_needed;
-	int repaint_scheduled;
+
+	/** State of the repaint loop */
+	enum {
+		REPAINT_NOT_SCHEDULED = 0, /**< idle; no repaint will occur */
+		REPAINT_SCHEDULED, /**< repaint is scheduled to occur */
+		REPAINT_AWAITING_COMPLETION, /**< last repaint not yet finished */
+	} repaint_status;
+
 	struct wl_event_source *repaint_timer;
 	struct weston_output_zoom zoom;
 	int dirty;
-- 
2.9.3



More information about the wayland-devel mailing list