aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_export_dmabuf_v1.h2
-rw-r--r--include/wlr/types/wlr_output.h8
-rw-r--r--types/wlr_export_dmabuf_v1.c23
-rw-r--r--types/wlr_output.c7
4 files changed, 34 insertions, 6 deletions
diff --git a/include/wlr/types/wlr_export_dmabuf_v1.h b/include/wlr/types/wlr_export_dmabuf_v1.h
index 78db1e61..4cb3393f 100644
--- a/include/wlr/types/wlr_export_dmabuf_v1.h
+++ b/include/wlr/types/wlr_export_dmabuf_v1.h
@@ -11,6 +11,8 @@ struct wlr_export_dmabuf_frame_v1 {
struct wl_list link;
struct wlr_output *output;
+
+ struct wl_listener output_swap_buffers;
};
struct wlr_export_dmabuf_manager_v1 {
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h
index 669b96ed..96c98dc3 100644
--- a/include/wlr/types/wlr_output.h
+++ b/include/wlr/types/wlr_output.h
@@ -82,7 +82,7 @@ struct wlr_output {
struct {
struct wl_signal frame;
struct wl_signal needs_swap;
- struct wl_signal swap_buffers;
+ struct wl_signal swap_buffers; // wlr_output_event_swap_buffers
struct wl_signal enable;
struct wl_signal mode;
struct wl_signal scale;
@@ -108,6 +108,12 @@ struct wlr_output {
void *data;
};
+struct wlr_output_event_swap_buffers {
+ struct wlr_output *output;
+ struct timespec *when;
+ pixman_region32_t *damage;
+};
+
struct wlr_surface;
void wlr_output_enable(struct wlr_output *output, bool enable);
diff --git a/types/wlr_export_dmabuf_v1.c b/types/wlr_export_dmabuf_v1.c
index fa732397..2f1c88f2 100644
--- a/types/wlr_export_dmabuf_v1.c
+++ b/types/wlr_export_dmabuf_v1.c
@@ -30,9 +30,25 @@ static const struct zwlr_export_dmabuf_frame_v1_interface frame_impl = {
static void frame_handle_resource_destroy(struct wl_resource *resource) {
struct wlr_export_dmabuf_frame_v1 *frame = frame_from_resource(resource);
wl_list_remove(&frame->link);
+ wl_list_remove(&frame->output_swap_buffers.link);
free(frame);
}
+static void frame_output_handle_swap_buffers(struct wl_listener *listener,
+ void *data) {
+ struct wlr_export_dmabuf_frame_v1 *frame =
+ wl_container_of(listener, frame, output_swap_buffers);
+ struct wlr_output_event_swap_buffers *event = data;
+
+ wl_list_remove(&frame->output_swap_buffers.link);
+ wl_list_init(&frame->output_swap_buffers.link);
+
+ uint32_t tv_sec_hi = event->when->tv_sec << 32;
+ uint32_t tv_sec_lo = event->when->tv_sec & 0xFFFFFFFF;
+ zwlr_export_dmabuf_frame_v1_send_ready(frame->resource,
+ tv_sec_hi, tv_sec_lo, event->when->tv_nsec);
+}
+
static const struct zwlr_export_dmabuf_manager_v1_interface manager_impl;
@@ -87,7 +103,7 @@ static void manager_handle_capture_output(struct wl_client *client,
uint32_t frame_flags = 0;
uint32_t mod_high = attribs.modifier[0] >> 32;
- uint32_t mod_low = attribs.modifier[0];
+ uint32_t mod_low = attribs.modifier[0] & 0xFFFFFFFF;
zwlr_export_dmabuf_frame_v1_send_frame(frame->resource,
output->width, output->height, output->scale, output->transform,
@@ -106,9 +122,8 @@ static void manager_handle_capture_output(struct wl_client *client,
attribs.offset[i], attribs.stride[i]);
}
- // TODO: wait for the frame to be ready
- // TODO: timestamps
- zwlr_export_dmabuf_frame_v1_send_ready(frame->resource, 0, 0, 0);
+ frame->output_swap_buffers.notify = frame_output_handle_swap_buffers;
+ wl_signal_add(&output->events.swap_buffers, &frame->output_swap_buffers);
}
static const struct zwlr_export_dmabuf_manager_v1_interface manager_impl = {
diff --git a/types/wlr_output.c b/types/wlr_output.c
index f7001b16..b0321d7f 100644
--- a/types/wlr_output.c
+++ b/types/wlr_output.c
@@ -467,7 +467,12 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
output->idle_frame = NULL;
}
- wlr_signal_emit_safe(&output->events.swap_buffers, damage);
+ struct wlr_output_event_swap_buffers event = {
+ .output = output,
+ .when = when,
+ .damage = damage,
+ };
+ wlr_signal_emit_safe(&output->events.swap_buffers, &event);
int width, height;
wlr_output_transformed_resolution(output, &width, &height);