mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 21:05:58 +01:00
presentation-time: add separate helper for zero-copy
The backend is not able to tell whether a surface is being presented via direct scan-out or not. The backend will set ZERO_COPY if the buffer submitted via the output commit was presented in a zero-copy fashion, but will no know whether the buffer comes from the compositor or the client.
This commit is contained in:
parent
fe84bfc8d9
commit
67447d6cb4
3 changed files with 48 additions and 14 deletions
|
@ -33,11 +33,12 @@ struct wlr_presentation {
|
||||||
struct wlr_presentation_feedback {
|
struct wlr_presentation_feedback {
|
||||||
struct wl_list resources; // wl_resource_get_link()
|
struct wl_list resources; // wl_resource_get_link()
|
||||||
|
|
||||||
// Only when the wlr_presentation_surface_sampled_on_output() helper has
|
// Only when the wlr_presentation_surface_textured_on_output() or
|
||||||
// been called.
|
// wlr_presentation_surface_scanned_out_on_output() helper has been called.
|
||||||
struct wlr_output *output;
|
struct wlr_output *output;
|
||||||
bool output_committed;
|
bool output_committed;
|
||||||
uint32_t output_commit_seq;
|
uint32_t output_commit_seq;
|
||||||
|
bool zero_copy;
|
||||||
|
|
||||||
struct wl_listener output_commit;
|
struct wl_listener output_commit;
|
||||||
struct wl_listener output_present;
|
struct wl_listener output_present;
|
||||||
|
@ -85,14 +86,23 @@ void wlr_presentation_event_from_output(struct wlr_presentation_event *event,
|
||||||
const struct wlr_output_event_present *output_event);
|
const struct wlr_output_event_present *output_event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the current surface's buffer as sampled on the given output.
|
* Mark the current surface's buffer as textured on the given output.
|
||||||
*
|
*
|
||||||
* Instead of calling wlr_presentation_surface_sampled() and managing the
|
* Instead of calling wlr_presentation_surface_sampled() and managing the
|
||||||
* struct wlr_presentation_feedback itself, the compositor can call this function
|
* struct wlr_presentation_feedback itself, the compositor can call this function
|
||||||
* before a wlr_output_commit() call to indicate that the surface's current
|
* before a wlr_output_commit() call to indicate that the surface's current
|
||||||
* contents will be displayed on the output.
|
* contents have been copied to a buffer which will be displayed on the output.
|
||||||
*/
|
*/
|
||||||
void wlr_presentation_surface_sampled_on_output(
|
void wlr_presentation_surface_textured_on_output(
|
||||||
|
struct wlr_presentation *presentation, struct wlr_surface *surface,
|
||||||
|
struct wlr_output *output);
|
||||||
|
/**
|
||||||
|
* Mark the current surface's buffer as scanned out on the given output.
|
||||||
|
*
|
||||||
|
* Same as wlr_presentation_surface_textured_on_output(), but indicates direct
|
||||||
|
* scan-out.
|
||||||
|
*/
|
||||||
|
void wlr_presentation_surface_scanned_out_on_output(
|
||||||
struct wlr_presentation *presentation, struct wlr_surface *surface,
|
struct wlr_presentation *presentation, struct wlr_surface *surface,
|
||||||
struct wlr_output *output);
|
struct wlr_output *output);
|
||||||
|
|
||||||
|
|
|
@ -42,15 +42,21 @@ static void handle_scene_buffer_output_sample(
|
||||||
wl_container_of(listener, surface, output_sample);
|
wl_container_of(listener, surface, output_sample);
|
||||||
const struct wlr_scene_output_sample_event *event = data;
|
const struct wlr_scene_output_sample_event *event = data;
|
||||||
struct wlr_scene_output *scene_output = event->output;
|
struct wlr_scene_output *scene_output = event->output;
|
||||||
|
if (surface->buffer->primary_output != scene_output) {
|
||||||
if (surface->buffer->primary_output == scene_output) {
|
return;
|
||||||
struct wlr_scene *root = scene_node_get_root(&surface->buffer->node);
|
|
||||||
struct wlr_presentation *presentation = root->presentation;
|
|
||||||
|
|
||||||
if (presentation) {
|
|
||||||
wlr_presentation_surface_sampled_on_output(
|
|
||||||
presentation, surface->surface, scene_output->output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_scene *root = scene_node_get_root(&surface->buffer->node);
|
||||||
|
if (!root->presentation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event->direct_scanout) {
|
||||||
|
wlr_presentation_surface_scanned_out_on_output(
|
||||||
|
root->presentation, surface->surface, scene_output->output);
|
||||||
|
} else {
|
||||||
|
wlr_presentation_surface_textured_on_output(
|
||||||
|
root->presentation, surface->surface, scene_output->output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -295,6 +295,9 @@ static void feedback_handle_output_present(struct wl_listener *listener,
|
||||||
if (output_event->presented) {
|
if (output_event->presented) {
|
||||||
struct wlr_presentation_event event = {0};
|
struct wlr_presentation_event event = {0};
|
||||||
wlr_presentation_event_from_output(&event, output_event);
|
wlr_presentation_event_from_output(&event, output_event);
|
||||||
|
if (!feedback->zero_copy) {
|
||||||
|
event.flags &= ~WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY;
|
||||||
|
}
|
||||||
wlr_presentation_feedback_send_presented(feedback, &event);
|
wlr_presentation_feedback_send_presented(feedback, &event);
|
||||||
}
|
}
|
||||||
wlr_presentation_feedback_destroy(feedback);
|
wlr_presentation_feedback_destroy(feedback);
|
||||||
|
@ -307,9 +310,9 @@ static void feedback_handle_output_destroy(struct wl_listener *listener,
|
||||||
wlr_presentation_feedback_destroy(feedback);
|
wlr_presentation_feedback_destroy(feedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_presentation_surface_sampled_on_output(
|
static void presentation_surface_queued_on_output(
|
||||||
struct wlr_presentation *presentation, struct wlr_surface *surface,
|
struct wlr_presentation *presentation, struct wlr_surface *surface,
|
||||||
struct wlr_output *output) {
|
struct wlr_output *output, bool zero_copy) {
|
||||||
struct wlr_presentation_feedback *feedback =
|
struct wlr_presentation_feedback *feedback =
|
||||||
wlr_presentation_surface_sampled(presentation, surface);
|
wlr_presentation_surface_sampled(presentation, surface);
|
||||||
if (feedback == NULL) {
|
if (feedback == NULL) {
|
||||||
|
@ -318,6 +321,7 @@ void wlr_presentation_surface_sampled_on_output(
|
||||||
|
|
||||||
assert(feedback->output == NULL);
|
assert(feedback->output == NULL);
|
||||||
feedback->output = output;
|
feedback->output = output;
|
||||||
|
feedback->zero_copy = zero_copy;
|
||||||
|
|
||||||
feedback->output_commit.notify = feedback_handle_output_commit;
|
feedback->output_commit.notify = feedback_handle_output_commit;
|
||||||
wl_signal_add(&output->events.commit, &feedback->output_commit);
|
wl_signal_add(&output->events.commit, &feedback->output_commit);
|
||||||
|
@ -326,3 +330,17 @@ void wlr_presentation_surface_sampled_on_output(
|
||||||
feedback->output_destroy.notify = feedback_handle_output_destroy;
|
feedback->output_destroy.notify = feedback_handle_output_destroy;
|
||||||
wl_signal_add(&output->events.destroy, &feedback->output_destroy);
|
wl_signal_add(&output->events.destroy, &feedback->output_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wlr_presentation_surface_textured_on_output(
|
||||||
|
struct wlr_presentation *presentation, struct wlr_surface *surface,
|
||||||
|
struct wlr_output *output) {
|
||||||
|
return presentation_surface_queued_on_output(presentation, surface,
|
||||||
|
output, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_presentation_surface_scanned_out_on_output(
|
||||||
|
struct wlr_presentation *presentation, struct wlr_surface *surface,
|
||||||
|
struct wlr_output *output) {
|
||||||
|
return presentation_surface_queued_on_output(presentation, surface,
|
||||||
|
output, true);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue