mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2025-12-20 04:40:07 +01:00
output: Record paint_node_changes during repaint
When we're going through assign_planes and repaint, give the backend an opportunity to see what's changed during this repaint. Signed-off-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
parent
7f8c5f984e
commit
0664d5bdc1
3 changed files with 137 additions and 2 deletions
|
|
@ -353,6 +353,9 @@ struct weston_output {
|
|||
/* struct weston_paint_node::output_link */
|
||||
struct wl_list paint_node_list;
|
||||
|
||||
/** Only valid during repaint: changes for this repaint */
|
||||
enum weston_paint_node_status paint_node_changes;
|
||||
|
||||
/** From global to output buffer coordinates. */
|
||||
struct weston_matrix matrix;
|
||||
/** From output buffer to global coordinates. */
|
||||
|
|
|
|||
|
|
@ -257,6 +257,7 @@ paint_node_update_early(struct weston_paint_node *pnode)
|
|||
get_placeholder_color(pnode, &pnode->solid);
|
||||
}
|
||||
|
||||
pnode->output->paint_node_changes |= pnode->status;
|
||||
pnode->status &= ~(WESTON_PAINT_NODE_VIEW_DIRTY | \
|
||||
WESTON_PAINT_NODE_OUTPUT_DIRTY);
|
||||
}
|
||||
|
|
@ -3620,8 +3621,10 @@ weston_output_repaint(struct weston_output *output)
|
|||
TL_POINT(ec, TLP_CORE_REPAINT_BEGIN, TLP_OUTPUT(output), TLP_END);
|
||||
|
||||
/* Rebuild the surface list and update surface transforms up front. */
|
||||
if (ec->view_list_needs_rebuild)
|
||||
if (ec->view_list_needs_rebuild) {
|
||||
weston_compositor_build_view_list(ec);
|
||||
output->paint_node_changes = WESTON_PAINT_NODE_ALL_DIRTY;
|
||||
}
|
||||
|
||||
/* If the scene graph is empty, we could end up passing a buffer
|
||||
* we've never drawn into to a hardware plane later. If that hardware
|
||||
|
|
@ -3736,8 +3739,11 @@ weston_output_repaint(struct weston_output *output)
|
|||
* to trigger a new repaint, so drop it from repaint and hope
|
||||
* something schedules a successful repaint later.
|
||||
*/
|
||||
if (r != 0)
|
||||
if (r == 0) {
|
||||
output->paint_node_changes = WESTON_PAINT_NODE_CLEAN;
|
||||
} else {
|
||||
weston_output_schedule_repaint_reset(output);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,132 @@ DECLARE_LIST_ITERATOR(output, struct weston_compositor, output_list,
|
|||
DECLARE_LIST_ITERATOR(pnode_from_z, struct weston_output, paint_node_z_order_list,
|
||||
struct weston_paint_node, z_order_link);
|
||||
|
||||
static enum weston_paint_node_status
|
||||
get_paint_node_status(struct client *client,
|
||||
struct wet_testsuite_data *suite_data)
|
||||
{
|
||||
enum weston_paint_node_status changes;
|
||||
|
||||
RUN_INSIDE_BREAKPOINT(client, suite_data) {
|
||||
struct weston_compositor *compositor;
|
||||
struct weston_output *output;
|
||||
struct weston_head *head;
|
||||
|
||||
test_assert_enum(breakpoint->template_->breakpoint,
|
||||
WESTON_TEST_BREAKPOINT_POST_REPAINT);
|
||||
compositor = breakpoint->compositor;
|
||||
head = breakpoint->resource;
|
||||
output = next_output(compositor, NULL);
|
||||
test_assert_ptr_eq(output, head->output);
|
||||
test_assert_str_eq(output->name, "headless");
|
||||
test_assert_ptr_null(next_output(compositor, output));
|
||||
changes = output->paint_node_changes;
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
TEST(paint_node_status_on_repaint)
|
||||
{
|
||||
struct wet_testsuite_data *suite_data = TEST_GET_SUITE_DATA();
|
||||
struct client *client;
|
||||
struct buffer *buf1, *buf2, *buf3;
|
||||
enum weston_paint_node_status changes;
|
||||
struct surface *new_surf;
|
||||
struct rectangle opaque = { .x = 0, .y = 0, .width = 100, .height = 100 };
|
||||
pixman_color_t red;
|
||||
|
||||
color_rgb888(&red, 255, 0, 0);
|
||||
|
||||
client = create_client();
|
||||
test_assert_ptr_not_null(client);
|
||||
|
||||
client->surface = create_test_surface(client);
|
||||
|
||||
client_push_breakpoint(client, suite_data,
|
||||
WESTON_TEST_BREAKPOINT_POST_REPAINT,
|
||||
(struct wl_proxy *) client->output->wl_output);
|
||||
weston_test_move_surface(client->test->weston_test, client->surface->wl_surface,
|
||||
50, 50);
|
||||
buf1 = surface_commit_color(client, client->surface->wl_surface, &red, 100, 100);
|
||||
changes = get_paint_node_status(client, suite_data);
|
||||
test_assert_enum(changes, WESTON_PAINT_NODE_ALL_DIRTY);
|
||||
|
||||
/* move the surface */
|
||||
client_push_breakpoint(client, suite_data,
|
||||
WESTON_TEST_BREAKPOINT_POST_REPAINT,
|
||||
(struct wl_proxy *) client->output->wl_output);
|
||||
weston_test_move_surface(client->test->weston_test, client->surface->wl_surface,
|
||||
80, 80);
|
||||
wl_surface_attach(client->surface->wl_surface, buf1->proxy, 0, 0);
|
||||
wl_surface_damage_buffer(client->surface->wl_surface, 0, 0, 200, 200);
|
||||
wl_surface_commit(client->surface->wl_surface);
|
||||
changes = get_paint_node_status(client, suite_data);
|
||||
test_assert_enum(changes,
|
||||
(WESTON_PAINT_NODE_BUFFER_DIRTY |
|
||||
WESTON_PAINT_NODE_VIEW_DIRTY |
|
||||
WESTON_PAINT_NODE_VISIBILITY_DIRTY));
|
||||
|
||||
/* a new buffer */
|
||||
client_push_breakpoint(client, suite_data,
|
||||
WESTON_TEST_BREAKPOINT_POST_REPAINT,
|
||||
(struct wl_proxy *) client->output->wl_output);
|
||||
buf2 = surface_commit_color(client, client->surface->wl_surface, &red, 100, 100);
|
||||
changes = get_paint_node_status(client, suite_data);
|
||||
test_assert_enum(changes, WESTON_PAINT_NODE_BUFFER_DIRTY);
|
||||
|
||||
/* a buffer with updated dimensions */
|
||||
client_push_breakpoint(client, suite_data,
|
||||
WESTON_TEST_BREAKPOINT_POST_REPAINT,
|
||||
(struct wl_proxy *) client->output->wl_output);
|
||||
buf3 = surface_commit_color(client, client->surface->wl_surface, &red, 200, 200);
|
||||
changes = get_paint_node_status(client, suite_data);
|
||||
test_assert_enum(changes,
|
||||
(WESTON_PAINT_NODE_BUFFER_DIRTY |
|
||||
WESTON_PAINT_NODE_VIEW_DIRTY |
|
||||
WESTON_PAINT_NODE_VISIBILITY_DIRTY));
|
||||
|
||||
/* an opaque buffer moving will change visibility */
|
||||
client_push_breakpoint(client, suite_data,
|
||||
WESTON_TEST_BREAKPOINT_POST_REPAINT,
|
||||
(struct wl_proxy *) client->output->wl_output);
|
||||
surface_set_opaque_rect(client->surface, &opaque);
|
||||
weston_test_move_surface(client->test->weston_test, client->surface->wl_surface,
|
||||
100, 100);
|
||||
wl_surface_attach(client->surface->wl_surface, buf3->proxy, 0, 0);
|
||||
wl_surface_damage_buffer(client->surface->wl_surface, 0, 0, 200, 200);
|
||||
wl_surface_commit(client->surface->wl_surface);
|
||||
changes = get_paint_node_status(client, suite_data);
|
||||
test_assert_enum(changes,
|
||||
(WESTON_PAINT_NODE_BUFFER_DIRTY |
|
||||
WESTON_PAINT_NODE_VIEW_DIRTY |
|
||||
WESTON_PAINT_NODE_VISIBILITY_DIRTY));
|
||||
|
||||
/* a new surface rebuilds the view list */
|
||||
client_push_breakpoint(client, suite_data,
|
||||
WESTON_TEST_BREAKPOINT_POST_REPAINT,
|
||||
(struct wl_proxy *) client->output->wl_output);
|
||||
new_surf = create_test_surface(client);
|
||||
weston_test_move_surface(client->test->weston_test,
|
||||
new_surf->wl_surface,
|
||||
5, 5);
|
||||
wl_surface_attach(new_surf->wl_surface, buf1->proxy, 0, 0);
|
||||
wl_surface_damage_buffer(new_surf->wl_surface, 0, 0, 200, 200);
|
||||
wl_surface_commit(new_surf->wl_surface);
|
||||
changes = get_paint_node_status(client, suite_data);
|
||||
test_assert_enum(changes, WESTON_PAINT_NODE_ALL_DIRTY);
|
||||
|
||||
buffer_destroy(buf1);
|
||||
buffer_destroy(buf2);
|
||||
buffer_destroy(buf3);
|
||||
surface_destroy(new_surf);
|
||||
client_destroy(client);
|
||||
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
TEST(top_surface_present_in_output_repaint)
|
||||
{
|
||||
struct wet_testsuite_data *suite_data = TEST_GET_SUITE_DATA();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue