diff options
-rw-r--r-- | include/wlr/types/wlr_presentation_time.h | 10 | ||||
-rw-r--r-- | types/wlr_presentation_time.c | 20 |
2 files changed, 26 insertions, 4 deletions
diff --git a/include/wlr/types/wlr_presentation_time.h b/include/wlr/types/wlr_presentation_time.h index c80f6966..bf1d3ac2 100644 --- a/include/wlr/types/wlr_presentation_time.h +++ b/include/wlr/types/wlr_presentation_time.h @@ -31,9 +31,15 @@ struct wlr_presentation_feedback { struct wl_resource *resource; struct wlr_presentation *presentation; struct wlr_surface *surface; - bool committed; struct wl_list link; // wlr_presentation::feedbacks + // The surface contents were committed. + bool committed; + // The surface contents were sampled by the compositor and are to be + // presented on the next flip. Can become true only after committed becomes + // true. + bool sampled; + struct wl_listener surface_commit; struct wl_listener surface_destroy; }; @@ -55,5 +61,7 @@ void wlr_presentation_destroy(struct wlr_presentation *presentation); void wlr_presentation_send_surface_presented( struct wlr_presentation *presentation, struct wlr_surface *surface, struct wlr_presentation_event *event); +void wlr_presentation_surface_sampled( + struct wlr_presentation *presentation, struct wlr_surface *surface); #endif diff --git a/types/wlr_presentation_time.c b/types/wlr_presentation_time.c index eeba47b6..3c49e2fb 100644 --- a/types/wlr_presentation_time.c +++ b/types/wlr_presentation_time.c @@ -61,8 +61,10 @@ static void feedback_handle_surface_commit(struct wl_listener *listener, wl_container_of(listener, feedback, surface_commit); if (feedback->committed) { - // The content update has been superseded - feedback_send_discarded(feedback); + if (!feedback->sampled) { + // The content update has been superseded + feedback_send_discarded(feedback); + } } else { feedback->committed = true; } @@ -216,8 +218,20 @@ void wlr_presentation_send_surface_presented( struct wlr_presentation_feedback *feedback, *feedback_tmp; wl_list_for_each_safe(feedback, feedback_tmp, &presentation->feedbacks, link) { - if (feedback->surface == surface && feedback->committed) { + if (feedback->surface == surface && feedback->sampled) { feedback_send_presented(feedback, event); } } } + +void wlr_presentation_surface_sampled( + struct wlr_presentation *presentation, struct wlr_surface *surface) { + // TODO: maybe use a hashtable to optimize this function + struct wlr_presentation_feedback *feedback, *feedback_tmp; + wl_list_for_each_safe(feedback, feedback_tmp, + &presentation->feedbacks, link) { + if (feedback->surface == surface && feedback->committed) { + feedback->sampled = true; + } + } +} |