aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremersion <contact@emersion.fr>2018-10-02 11:46:28 +0200
committeremersion <contact@emersion.fr>2018-10-04 22:00:23 +0200
commitabd3e995ab446b5487f4d2ff16d9e2c3f1baade1 (patch)
tree1223b80afb2d04698c5193d8b85b20f49dadbdaa
parentba63d77ec19b84c9bf9be24cc4d91f3bfa856dba (diff)
rootston: send presentation events
-rw-r--r--include/rootston/desktop.h2
-rw-r--r--include/rootston/output.h1
-rw-r--r--rootston/desktop.c3
-rw-r--r--rootston/output.c52
4 files changed, 57 insertions, 1 deletions
diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h
index 90851a17..8cee170f 100644
--- a/include/rootston/desktop.h
+++ b/include/rootston/desktop.h
@@ -13,6 +13,7 @@
#include <wlr/types/wlr_list.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output.h>
+#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_screencopy_v1.h>
#include <wlr/types/wlr_screenshooter.h>
@@ -57,6 +58,7 @@ struct roots_desktop {
struct wlr_screencopy_manager_v1 *screencopy;
struct wlr_tablet_manager_v2 *tablet_v2;
struct wlr_pointer_constraints_v1 *pointer_constraints;
+ struct wlr_presentation *presentation;
struct wl_listener new_output;
struct wl_listener layout_change;
diff --git a/include/rootston/output.h b/include/rootston/output.h
index 69bc5126..3f07ab6f 100644
--- a/include/rootston/output.h
+++ b/include/rootston/output.h
@@ -24,6 +24,7 @@ struct roots_output {
struct wl_listener destroy;
struct wl_listener mode;
struct wl_listener transform;
+ struct wl_listener present;
struct wl_listener damage_frame;
struct wl_listener damage_destroy;
};
diff --git a/rootston/desktop.c b/rootston/desktop.c
index c180c839..7f749050 100644
--- a/rootston/desktop.c
+++ b/rootston/desktop.c
@@ -969,6 +969,9 @@ struct roots_desktop *desktop_create(struct roots_server *server,
wl_signal_add(&desktop->pointer_constraints->events.new_constraint,
&desktop->pointer_constraint);
+ desktop->presentation =
+ wlr_presentation_create(server->wl_display, server->backend);
+
return desktop;
}
diff --git a/rootston/output.c b/rootston/output.c
index 1707be3a..8168a0c3 100644
--- a/rootston/output.c
+++ b/rootston/output.c
@@ -5,9 +5,10 @@
#include <time.h>
#include <wlr/backend/drm.h>
#include <wlr/config.h>
-#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_compositor.h>
+#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output_layout.h>
+#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_wl_shell.h>
#include <wlr/types/wlr_xdg_shell_v6.h>
#include <wlr/types/wlr_xdg_shell.h>
@@ -784,6 +785,7 @@ static void output_destroy(struct roots_output *output) {
wl_list_remove(&output->destroy.link);
wl_list_remove(&output->mode.link);
wl_list_remove(&output->transform.link);
+ wl_list_remove(&output->present.link);
wl_list_remove(&output->damage_frame.link);
wl_list_remove(&output->damage_destroy.link);
free(output);
@@ -820,6 +822,52 @@ static void output_handle_transform(struct wl_listener *listener, void *data) {
arrange_layers(output);
}
+struct presentation_data {
+ struct layout_data layout;
+ struct roots_output *output;
+ struct wlr_presentation_event *event;
+};
+
+static void surface_send_presented(struct wlr_surface *surface, int sx, int sy,
+ void *_data) {
+ struct presentation_data *data = _data;
+ struct roots_output *output = data->output;
+ float rotation = data->layout.rotation;
+
+ double lx, ly;
+ get_layout_position(&data->layout, &lx, &ly, surface, sx, sy);
+
+ if (!surface_intersect_output(surface, output->desktop->layout,
+ output->wlr_output, lx, ly, rotation, NULL)) {
+ return;
+ }
+
+ wlr_presentation_send_surface_presented(output->desktop->presentation,
+ surface, data->event);
+}
+
+static void output_handle_present(struct wl_listener *listener, void *data) {
+ struct roots_output *output =
+ wl_container_of(listener, output, present);
+ struct wlr_output_event_present *output_event = data;
+
+ struct wlr_presentation_event event = {
+ .output = output->wlr_output,
+ .tv_sec = (uint64_t)output_event->when->tv_sec,
+ .tv_nsec = (uint32_t)output_event->when->tv_nsec,
+ .refresh = 0, // TODO: predict next output vsync delay
+ .seq = (uint64_t)output_event->seq,
+ .flags = output_event->flags,
+ };
+
+ struct presentation_data presentation_data = {
+ .output = output,
+ .event = &event,
+ };
+ output_for_each_surface(output, surface_send_presented,
+ &presentation_data.layout, &presentation_data);
+}
+
void handle_new_output(struct wl_listener *listener, void *data) {
struct roots_desktop *desktop = wl_container_of(listener, desktop,
new_output);
@@ -847,6 +895,8 @@ void handle_new_output(struct wl_listener *listener, void *data) {
wl_signal_add(&wlr_output->events.mode, &output->mode);
output->transform.notify = output_handle_transform;
wl_signal_add(&wlr_output->events.transform, &output->transform);
+ output->present.notify = output_handle_present;
+ wl_signal_add(&wlr_output->events.present, &output->present);
output->damage_frame.notify = output_damage_handle_frame;
wl_signal_add(&output->damage->events.frame, &output->damage_frame);