wlr_scene: Simplify direct scanout handling

By adding a sent_feedback bool into the list entry that we can mutate
we no longer need to maintain this `sent_direct_scanout_feedback` variable.

sent_feedback will also be useful later.
This commit is contained in:
Alexander Orzechowski 2023-03-10 13:35:31 +01:00
parent f9798fadf9
commit ac09d91baa

View file

@ -1365,6 +1365,7 @@ void wlr_scene_output_set_position(struct wlr_scene_output *scene_output,
struct render_list_entry { struct render_list_entry {
struct wlr_scene_node *node; struct wlr_scene_node *node;
bool sent_feedback;
bool visible; bool visible;
}; };
@ -1486,10 +1487,8 @@ static void scene_buffer_send_dmabuf_feedback(const struct wlr_scene *scene,
wlr_linux_dmabuf_feedback_v1_finish(&feedback); wlr_linux_dmabuf_feedback_v1_finish(&feedback);
} }
static bool scene_buffer_can_consider_direct_scanout(struct wlr_scene_buffer *buffer, static bool scene_buffer_try_direct_scanout(struct render_list_entry *entry,
const struct wlr_scene_output *scene_output) { struct wlr_scene_output *scene_output) {
struct wlr_scene_node *node = &buffer->node;
if (!scene_output->scene->direct_scanout) { if (!scene_output->scene->direct_scanout) {
return false; return false;
} }
@ -1501,13 +1500,16 @@ static bool scene_buffer_can_consider_direct_scanout(struct wlr_scene_buffer *bu
return false; return false;
} }
if (!wlr_output_is_direct_scanout_allowed(scene_output->output)) {
return false;
}
struct wlr_scene_node *node = entry->node;
if (node->type != WLR_SCENE_NODE_BUFFER) { if (node->type != WLR_SCENE_NODE_BUFFER) {
return false; return false;
} }
if (!wlr_output_is_direct_scanout_allowed(scene_output->output)) { struct wlr_scene_buffer *buffer = wlr_scene_buffer_from_node(node);
return false;
}
struct wlr_fbox default_box = {0}; struct wlr_fbox default_box = {0};
if (buffer->transform & WL_OUTPUT_TRANSFORM_90) { if (buffer->transform & WL_OUTPUT_TRANSFORM_90) {
@ -1542,11 +1544,16 @@ static bool scene_buffer_can_consider_direct_scanout(struct wlr_scene_buffer *bu
return false; return false;
} }
return true; if (buffer->primary_output == scene_output) {
} struct wlr_linux_dmabuf_feedback_v1_init_options options = {
.main_renderer = scene_output->output->renderer,
.scanout_primary_output = scene_output->output,
};
scene_buffer_send_dmabuf_feedback(scene_output->scene, buffer, &options);
entry->sent_feedback = true;
}
static bool scene_buffer_try_direct_scanout(struct wlr_scene_buffer *buffer,
struct wlr_scene_output *scene_output) {
struct wlr_output_state state = { struct wlr_output_state state = {
.committed = WLR_OUTPUT_STATE_BUFFER, .committed = WLR_OUTPUT_STATE_BUFFER,
.buffer = buffer->buffer, .buffer = buffer->buffer,
@ -1601,8 +1608,6 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
struct render_list_entry *scanout = NULL; struct render_list_entry *scanout = NULL;
int render_count = 0; int render_count = 0;
bool sent_direct_scanout_feedback = false;
for (int i = list_len - 1; i >= 0; i--) { for (int i = list_len - 1; i >= 0; i--) {
struct render_list_entry *entry = &list_data[i]; struct render_list_entry *entry = &list_data[i];
if (!entry->visible) { if (!entry->visible) {
@ -1613,32 +1618,11 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
render_count++; render_count++;
} }
// if there is only one thing to render let's see if that thing can be if (render_count != 1 || !scene_buffer_try_direct_scanout(scanout, scene_output)) {
// directly scanned out scanout = NULL;
bool really_scanout = false;;
if (render_count == 1) {
struct wlr_scene_node *node = scanout->node;
if (node->type == WLR_SCENE_NODE_BUFFER) {
struct wlr_scene_buffer *buffer = wlr_scene_buffer_from_node(node);
if (scene_buffer_can_consider_direct_scanout(buffer, scene_output)) {
if (buffer->primary_output == scene_output) {
struct wlr_linux_dmabuf_feedback_v1_init_options options = {
.main_renderer = output->renderer,
.scanout_primary_output = output,
};
scene_buffer_send_dmabuf_feedback(scene_output->scene, buffer, &options);
sent_direct_scanout_feedback = true;
}
really_scanout = scene_buffer_try_direct_scanout(buffer, scene_output);
}
}
} }
if (scene_output->prev_scanout != !!scanout) { if (scene_output->prev_scanout == !scanout) {
scene_output->prev_scanout = scanout; scene_output->prev_scanout = scanout;
wlr_log(WLR_DEBUG, "Direct scan-out %s", wlr_log(WLR_DEBUG, "Direct scan-out %s",
scanout ? "enabled" : "disabled"); scanout ? "enabled" : "disabled");
@ -1648,7 +1632,7 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
} }
} }
if (really_scanout) { if (scanout) {
return true; return true;
} }
@ -1774,7 +1758,7 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
if (entry->node->type == WLR_SCENE_NODE_BUFFER) { if (entry->node->type == WLR_SCENE_NODE_BUFFER) {
struct wlr_scene_buffer *buffer = wlr_scene_buffer_from_node(entry->node); struct wlr_scene_buffer *buffer = wlr_scene_buffer_from_node(entry->node);
if (buffer->primary_output == scene_output && !sent_direct_scanout_feedback) { if (buffer->primary_output == scene_output && !entry->sent_feedback) {
struct wlr_linux_dmabuf_feedback_v1_init_options options = { struct wlr_linux_dmabuf_feedback_v1_init_options options = {
.main_renderer = output->renderer, .main_renderer = output->renderer,
.scanout_primary_output = NULL, .scanout_primary_output = NULL,