aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_presentation_time.h10
-rw-r--r--types/wlr_presentation_time.c20
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;
+ }
+ }
+}