mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-13 08:22:16 -04:00
ext_image_capture_source_v1/output: wait for explicit sync
Synchronize from the scene render to the copy to capture client. Buffer return is still covered by implicit sync. We know this is the scene's render buffer, direct scanout is disallowed for the output capture source.
This commit is contained in:
parent
4a9692013d
commit
1433c1ee9e
4 changed files with 29 additions and 11 deletions
|
|
@ -15,6 +15,7 @@
|
|||
#include <time.h>
|
||||
|
||||
struct wlr_renderer;
|
||||
struct wlr_drm_syncobj_timeline;
|
||||
|
||||
struct wlr_ext_image_copy_capture_manager_v1 {
|
||||
struct wl_global *global;
|
||||
|
|
@ -82,6 +83,7 @@ void wlr_ext_image_copy_capture_frame_v1_fail(struct wlr_ext_image_copy_capture_
|
|||
* Copy a struct wlr_buffer into the client-provided buffer for the frame.
|
||||
*/
|
||||
bool wlr_ext_image_copy_capture_frame_v1_copy_buffer(struct wlr_ext_image_copy_capture_frame_v1 *frame,
|
||||
struct wlr_buffer *src, struct wlr_renderer *renderer);
|
||||
struct wlr_buffer *src, struct wlr_renderer *renderer,
|
||||
struct wlr_drm_syncobj_timeline *wait_timeline, uint64_t wait_point);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ struct wlr_ext_output_image_capture_source_v1_frame_event {
|
|||
struct wlr_ext_image_capture_source_v1_frame_event base;
|
||||
struct wlr_buffer *buffer;
|
||||
struct timespec when;
|
||||
struct wlr_drm_syncobj_timeline *wait_timeline;
|
||||
uint64_t wait_point;
|
||||
};
|
||||
|
||||
static void output_source_start(struct wlr_ext_image_capture_source_v1 *base,
|
||||
|
|
@ -86,7 +88,8 @@ static void output_source_copy_frame(struct wlr_ext_image_capture_source_v1 *bas
|
|||
wl_container_of(base_event, event, base);
|
||||
|
||||
if (wlr_ext_image_copy_capture_frame_v1_copy_buffer(frame,
|
||||
event->buffer, source->output->renderer)) {
|
||||
event->buffer, source->output->renderer,
|
||||
event->wait_timeline, event->wait_point)) {
|
||||
wlr_ext_image_copy_capture_frame_v1_ready(frame,
|
||||
source->output->transform, &event->when);
|
||||
}
|
||||
|
|
@ -152,6 +155,10 @@ static void source_handle_output_commit(struct wl_listener *listener,
|
|||
.buffer = buffer,
|
||||
.when = event->when, // TODO: predict next presentation time instead
|
||||
};
|
||||
if (event->state->committed & WLR_OUTPUT_STATE_WAIT_TIMELINE) {
|
||||
frame_event.wait_timeline = event->state->wait_timeline;
|
||||
frame_event.wait_point = event->state->wait_point;
|
||||
}
|
||||
wl_signal_emit_mutable(&source->base.events.frame, &frame_event);
|
||||
|
||||
pixman_region32_fini(&full_damage);
|
||||
|
|
@ -279,6 +286,8 @@ static void output_cursor_source_copy_frame(struct wlr_ext_image_capture_source_
|
|||
struct wlr_ext_image_copy_capture_frame_v1 *frame,
|
||||
struct wlr_ext_image_capture_source_v1_frame_event *base_event) {
|
||||
struct output_cursor_source *cursor_source = wl_container_of(base, cursor_source, base);
|
||||
struct wlr_ext_output_image_capture_source_v1_frame_event *event =
|
||||
wl_container_of(base_event, event, base);
|
||||
|
||||
struct wlr_buffer *src_buffer = cursor_source->output->cursor_front_buffer;
|
||||
if (src_buffer == NULL) {
|
||||
|
|
@ -287,7 +296,8 @@ static void output_cursor_source_copy_frame(struct wlr_ext_image_capture_source_
|
|||
}
|
||||
|
||||
if (!wlr_ext_image_copy_capture_frame_v1_copy_buffer(frame,
|
||||
src_buffer, cursor_source->output->renderer)) {
|
||||
src_buffer, cursor_source->output->renderer,
|
||||
event->wait_timeline, event->wait_point)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ static void source_copy_frame(struct wlr_ext_image_capture_source_v1 *base,
|
|||
struct scene_node_source_frame_event *event = wl_container_of(base_event, event, base);
|
||||
|
||||
if (wlr_ext_image_copy_capture_frame_v1_copy_buffer(frame,
|
||||
event->buffer, source->output.renderer)) {
|
||||
event->buffer, source->output.renderer, NULL, 0)) {
|
||||
wlr_ext_image_copy_capture_frame_v1_ready(frame,
|
||||
source->output.transform, &event->when);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,9 +105,9 @@ void wlr_ext_image_copy_capture_frame_v1_ready(struct wlr_ext_image_copy_capture
|
|||
frame_destroy(frame);
|
||||
}
|
||||
|
||||
static bool copy_dmabuf(struct wlr_buffer *dst,
|
||||
struct wlr_buffer *src, struct wlr_renderer *renderer,
|
||||
const pixman_region32_t *clip) {
|
||||
static bool copy_dmabuf(struct wlr_buffer *dst, struct wlr_buffer *src,
|
||||
struct wlr_renderer *renderer, const pixman_region32_t *clip,
|
||||
struct wlr_drm_syncobj_timeline *wait_timeline, uint64_t wait_point) {
|
||||
struct wlr_texture *texture = wlr_texture_from_buffer(renderer, src);
|
||||
if (texture == NULL) {
|
||||
return false;
|
||||
|
|
@ -123,6 +123,8 @@ static bool copy_dmabuf(struct wlr_buffer *dst,
|
|||
.texture = texture,
|
||||
.clip = clip,
|
||||
.blend_mode = WLR_RENDER_BLEND_MODE_NONE,
|
||||
.wait_timeline = wait_timeline,
|
||||
.wait_point = wait_point,
|
||||
});
|
||||
|
||||
ok = wlr_render_pass_submit(pass);
|
||||
|
|
@ -133,7 +135,8 @@ out:
|
|||
}
|
||||
|
||||
static bool copy_shm(void *data, uint32_t format, size_t stride,
|
||||
struct wlr_buffer *src, struct wlr_renderer *renderer) {
|
||||
struct wlr_buffer *src, struct wlr_renderer *renderer,
|
||||
struct wlr_drm_syncobj_timeline *wait_timeline, uint64_t wait_point) {
|
||||
// TODO: bypass renderer if source buffer supports data ptr access
|
||||
struct wlr_texture *texture = wlr_texture_from_buffer(renderer, src);
|
||||
if (!texture) {
|
||||
|
|
@ -145,6 +148,8 @@ static bool copy_shm(void *data, uint32_t format, size_t stride,
|
|||
.data = data,
|
||||
.format = format,
|
||||
.stride = stride,
|
||||
.wait_timeline = wait_timeline,
|
||||
.wait_point = wait_point,
|
||||
});
|
||||
|
||||
wlr_texture_destroy(texture);
|
||||
|
|
@ -153,7 +158,8 @@ static bool copy_shm(void *data, uint32_t format, size_t stride,
|
|||
}
|
||||
|
||||
bool wlr_ext_image_copy_capture_frame_v1_copy_buffer(struct wlr_ext_image_copy_capture_frame_v1 *frame,
|
||||
struct wlr_buffer *src, struct wlr_renderer *renderer) {
|
||||
struct wlr_buffer *src, struct wlr_renderer *renderer,
|
||||
struct wlr_drm_syncobj_timeline *wait_timeline, uint64_t wait_point) {
|
||||
struct wlr_buffer *dst = frame->buffer;
|
||||
|
||||
if (src->width != dst->width || src->height != dst->height) {
|
||||
|
|
@ -174,7 +180,7 @@ bool wlr_ext_image_copy_capture_frame_v1_copy_buffer(struct wlr_ext_image_copy_c
|
|||
ok = false;
|
||||
failure_reason = EXT_IMAGE_COPY_CAPTURE_FRAME_V1_FAILURE_REASON_BUFFER_CONSTRAINTS;
|
||||
} else {
|
||||
ok = copy_dmabuf(dst, src, renderer, &frame->buffer_damage);
|
||||
ok = copy_dmabuf(dst, src, renderer, &frame->buffer_damage, wait_timeline, wait_point);
|
||||
}
|
||||
} else if (wlr_buffer_begin_data_ptr_access(dst,
|
||||
WLR_BUFFER_DATA_PTR_ACCESS_WRITE, &data, &format, &stride)) {
|
||||
|
|
@ -182,7 +188,7 @@ bool wlr_ext_image_copy_capture_frame_v1_copy_buffer(struct wlr_ext_image_copy_c
|
|||
ok = false;
|
||||
failure_reason = EXT_IMAGE_COPY_CAPTURE_FRAME_V1_FAILURE_REASON_BUFFER_CONSTRAINTS;
|
||||
} else {
|
||||
ok = copy_shm(data, format, stride, src, renderer);
|
||||
ok = copy_shm(data, format, stride, src, renderer, wait_timeline, wait_point);
|
||||
}
|
||||
wlr_buffer_end_data_ptr_access(dst);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue