mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-13 08:22:16 -04:00
output, cursor: explicit sync for cursor surfaces
This commit is contained in:
parent
4a9692013d
commit
4050d4977d
5 changed files with 56 additions and 11 deletions
|
|
@ -111,7 +111,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
state->clear_color[3],
|
state->clear_color[3],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
wlr_output_add_software_cursors_to_render_pass(wlr_output, pass, NULL);
|
wlr_output_add_software_cursors_to_render_pass(wlr_output, pass, NULL, NULL, 0);
|
||||||
wlr_render_pass_submit(pass);
|
wlr_render_pass_submit(pass);
|
||||||
wlr_output_commit_state(wlr_output, &output_state);
|
wlr_output_commit_state(wlr_output, &output_state);
|
||||||
wlr_output_state_finish(&output_state);
|
wlr_output_state_finish(&output_state);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,11 @@ struct wlr_output_mode {
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wlr_output_cursor_texture_sample_event {
|
||||||
|
struct wlr_drm_syncobj_timeline *release_timeline;
|
||||||
|
uint64_t release_point;
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_output_cursor {
|
struct wlr_output_cursor {
|
||||||
struct wlr_output *output;
|
struct wlr_output *output;
|
||||||
double x, y;
|
double x, y;
|
||||||
|
|
@ -51,6 +56,10 @@ struct wlr_output_cursor {
|
||||||
uint64_t wait_point;
|
uint64_t wait_point;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct wl_signal texture_sample; // struct wlr_output_cursor_texture_sample_event
|
||||||
|
} events;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_listener renderer_destroy;
|
struct wl_listener renderer_destroy;
|
||||||
struct wlr_color_transform *color_transform;
|
struct wlr_color_transform *color_transform;
|
||||||
|
|
@ -442,7 +451,8 @@ void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock);
|
||||||
* This is a utility function that can be called when compositors render.
|
* This is a utility function that can be called when compositors render.
|
||||||
*/
|
*/
|
||||||
void wlr_output_add_software_cursors_to_render_pass(struct wlr_output *output,
|
void wlr_output_add_software_cursors_to_render_pass(struct wlr_output *output,
|
||||||
struct wlr_render_pass *render_pass, const pixman_region32_t *damage);
|
struct wlr_render_pass *render_pass, const pixman_region32_t *damage,
|
||||||
|
struct wlr_drm_syncobj_timeline *release_timeline, uint64_t release_point);
|
||||||
/**
|
/**
|
||||||
* Get the set of DRM formats suitable for the primary buffer, assuming a
|
* Get the set of DRM formats suitable for the primary buffer, assuming a
|
||||||
* buffer with the specified capabilities.
|
* buffer with the specified capabilities.
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,8 @@ static void output_cursor_get_box(struct wlr_output_cursor *cursor,
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_output_add_software_cursors_to_render_pass(struct wlr_output *output,
|
void wlr_output_add_software_cursors_to_render_pass(struct wlr_output *output,
|
||||||
struct wlr_render_pass *render_pass, const pixman_region32_t *damage) {
|
struct wlr_render_pass *render_pass, const pixman_region32_t *damage,
|
||||||
|
struct wlr_drm_syncobj_timeline *release_timeline, uint64_t release_point) {
|
||||||
int width, height;
|
int width, height;
|
||||||
wlr_output_transformed_resolution(output, &width, &height);
|
wlr_output_transformed_resolution(output, &width, &height);
|
||||||
|
|
||||||
|
|
@ -128,7 +129,14 @@ void wlr_output_add_software_cursors_to_render_pass(struct wlr_output *output,
|
||||||
.dst_box = box,
|
.dst_box = box,
|
||||||
.clip = &cursor_damage,
|
.clip = &cursor_damage,
|
||||||
.transform = output->transform,
|
.transform = output->transform,
|
||||||
|
.wait_timeline = cursor->wait_timeline,
|
||||||
|
.wait_point = cursor->wait_point,
|
||||||
});
|
});
|
||||||
|
struct wlr_output_cursor_texture_sample_event event = {
|
||||||
|
.release_timeline = release_timeline,
|
||||||
|
.release_point = release_point,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&cursor->events.texture_sample, &event);
|
||||||
|
|
||||||
pixman_region32_fini(&cursor_damage);
|
pixman_region32_fini(&cursor_damage);
|
||||||
}
|
}
|
||||||
|
|
@ -285,6 +293,9 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_output_cursor_texture_sample_event event = {0};
|
||||||
|
wl_signal_emit_mutable(&cursor->events.texture_sample, &event);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -472,6 +483,7 @@ struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output) {
|
||||||
cursor->output = output;
|
cursor->output = output;
|
||||||
wl_list_insert(&output->cursors, &cursor->link);
|
wl_list_insert(&output->cursors, &cursor->link);
|
||||||
cursor->visible = true; // default position is at (0, 0)
|
cursor->visible = true; // default position is at (0, 0)
|
||||||
|
wl_signal_init(&cursor->events.texture_sample);
|
||||||
wl_list_init(&cursor->renderer_destroy.link);
|
wl_list_init(&cursor->renderer_destroy.link);
|
||||||
output_cursor_refresh_color_transform(cursor, output->image_description);
|
output_cursor_refresh_color_transform(cursor, output->image_description);
|
||||||
return cursor;
|
return cursor;
|
||||||
|
|
@ -493,6 +505,7 @@ void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) {
|
||||||
}
|
}
|
||||||
wlr_drm_syncobj_timeline_unref(cursor->wait_timeline);
|
wlr_drm_syncobj_timeline_unref(cursor->wait_timeline);
|
||||||
wl_list_remove(&cursor->link);
|
wl_list_remove(&cursor->link);
|
||||||
|
assert(wl_list_empty(&cursor->events.texture_sample.listener_list));
|
||||||
wlr_color_transform_unref(cursor->color_transform);
|
wlr_color_transform_unref(cursor->color_transform);
|
||||||
free(cursor);
|
free(cursor);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2581,7 +2581,8 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_output_add_software_cursors_to_render_pass(output, render_pass, &render_data.damage);
|
wlr_output_add_software_cursors_to_render_pass(output, render_pass,
|
||||||
|
&render_data.damage, scene_output->in_timeline, scene_output->in_point);
|
||||||
pixman_region32_fini(&render_data.damage);
|
pixman_region32_fini(&render_data.damage);
|
||||||
|
|
||||||
if (!wlr_render_pass_submit(render_pass)) {
|
if (!wlr_render_pass_submit(render_pass)) {
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ struct wlr_cursor_output_cursor {
|
||||||
|
|
||||||
// only when using a surface as the cursor image
|
// only when using a surface as the cursor image
|
||||||
struct wl_listener output_commit;
|
struct wl_listener output_commit;
|
||||||
|
struct wl_listener texture_sample;
|
||||||
|
|
||||||
// only when using an XCursor as the cursor image
|
// only when using an XCursor as the cursor image
|
||||||
struct wlr_xcursor *xcursor;
|
struct wlr_xcursor *xcursor;
|
||||||
|
|
@ -160,6 +161,7 @@ static void output_cursor_destroy(struct wlr_cursor_output_cursor *output_cursor
|
||||||
wl_list_remove(&output_cursor->layout_output_destroy.link);
|
wl_list_remove(&output_cursor->layout_output_destroy.link);
|
||||||
wl_list_remove(&output_cursor->link);
|
wl_list_remove(&output_cursor->link);
|
||||||
wl_list_remove(&output_cursor->output_commit.link);
|
wl_list_remove(&output_cursor->output_commit.link);
|
||||||
|
wl_list_remove(&output_cursor->texture_sample.link);
|
||||||
wlr_output_cursor_destroy(output_cursor->output_cursor);
|
wlr_output_cursor_destroy(output_cursor->output_cursor);
|
||||||
free(output_cursor);
|
free(output_cursor);
|
||||||
}
|
}
|
||||||
|
|
@ -579,13 +581,6 @@ static void cursor_output_cursor_update(struct wlr_cursor_output_cursor *output_
|
||||||
&src_box, dst_width, dst_height, surface->current.transform,
|
&src_box, dst_width, dst_height, surface->current.transform,
|
||||||
hotspot_x, hotspot_y, wait_timeline, wait_point);
|
hotspot_x, hotspot_y, wait_timeline, wait_point);
|
||||||
|
|
||||||
if (syncobj_surface_state != NULL &&
|
|
||||||
surface->buffer != NULL && surface->buffer->source != NULL &&
|
|
||||||
(surface->current.committed & WLR_SURFACE_STATE_BUFFER)) {
|
|
||||||
wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer(syncobj_surface_state,
|
|
||||||
surface->buffer->source);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (output_cursor->output_cursor->visible) {
|
if (output_cursor->output_cursor->visible) {
|
||||||
wlr_surface_send_enter(surface, output);
|
wlr_surface_send_enter(surface, output);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -645,6 +640,29 @@ static void output_cursor_output_handle_output_commit(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void output_cursor_output_handle_texture_sample(
|
||||||
|
struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_cursor_output_cursor *output_cursor =
|
||||||
|
wl_container_of(listener, output_cursor, texture_sample);
|
||||||
|
const struct wlr_output_cursor_texture_sample_event *event = data;
|
||||||
|
|
||||||
|
struct wlr_surface *surface = output_cursor->cursor->state->surface;
|
||||||
|
struct wlr_linux_drm_syncobj_surface_v1_state *syncobj_state = NULL;
|
||||||
|
if (surface != NULL) {
|
||||||
|
syncobj_state = wlr_linux_drm_syncobj_v1_get_surface_state(surface);
|
||||||
|
}
|
||||||
|
if (syncobj_state != NULL) {
|
||||||
|
struct wl_event_loop *event_loop = output_cursor->output_cursor->output->event_loop;
|
||||||
|
if (event->release_timeline != NULL) {
|
||||||
|
wlr_linux_drm_syncobj_v1_state_add_release_point(syncobj_state,
|
||||||
|
event->release_timeline, event->release_point, event_loop);
|
||||||
|
} else if (surface->buffer != NULL && surface->buffer->source != NULL) {
|
||||||
|
wlr_linux_drm_syncobj_v1_state_add_release_from_implicit_sync(syncobj_state,
|
||||||
|
surface->buffer->source, event_loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void cursor_update_outputs(struct wlr_cursor *cur) {
|
static void cursor_update_outputs(struct wlr_cursor *cur) {
|
||||||
struct wlr_cursor_output_cursor *output_cursor;
|
struct wlr_cursor_output_cursor *output_cursor;
|
||||||
wl_list_for_each(output_cursor, &cur->state->output_cursors, link) {
|
wl_list_for_each(output_cursor, &cur->state->output_cursors, link) {
|
||||||
|
|
@ -1167,6 +1185,9 @@ static void layout_add(struct wlr_cursor_state *state,
|
||||||
wl_signal_add(&output_cursor->output_cursor->output->events.commit,
|
wl_signal_add(&output_cursor->output_cursor->output->events.commit,
|
||||||
&output_cursor->output_commit);
|
&output_cursor->output_commit);
|
||||||
output_cursor->output_commit.notify = output_cursor_output_handle_output_commit;
|
output_cursor->output_commit.notify = output_cursor_output_handle_output_commit;
|
||||||
|
wl_signal_add(&output_cursor->output_cursor->events.texture_sample,
|
||||||
|
&output_cursor->texture_sample);
|
||||||
|
output_cursor->texture_sample.notify = output_cursor_output_handle_texture_sample;
|
||||||
|
|
||||||
output_cursor_move(output_cursor);
|
output_cursor_move(output_cursor);
|
||||||
cursor_output_cursor_update(output_cursor);
|
cursor_output_cursor_update(output_cursor);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue