|
21 | 21 | #if WLR_HAS_X11_BACKEND |
22 | 22 | #include <wlr/backend/x11.h> |
23 | 23 | #endif |
| 24 | +#include <wlr/render/swapchain.h> |
24 | 25 | #include <wlr/render/wlr_renderer.h> |
25 | 26 | #include <wlr/types/wlr_compositor.h> |
26 | 27 | #include <wlr/types/wlr_data_device.h> |
27 | 28 | #include <wlr/types/wlr_output.h> |
28 | 29 | #include <wlr/types/wlr_output_layout.h> |
29 | 30 | #include <wlr/types/wlr_output_management_v1.h> |
| 31 | +#include <wlr/types/wlr_output_swapchain_manager.h> |
30 | 32 | #include <wlr/types/wlr_scene.h> |
31 | 33 | #include <wlr/types/wlr_xdg_shell.h> |
32 | 34 | #include <wlr/util/log.h> |
@@ -130,31 +132,6 @@ output_disable(struct cg_output *output) |
130 | 132 | output_layout_remove(output); |
131 | 133 | } |
132 | 134 |
|
133 | | -static bool |
134 | | -output_apply_config(struct cg_output *output, struct wlr_output_configuration_head_v1 *head, bool test_only) |
135 | | -{ |
136 | | - struct wlr_output_state state = {0}; |
137 | | - wlr_output_head_v1_state_apply(&head->state, &state); |
138 | | - |
139 | | - if (test_only) { |
140 | | - bool ret = wlr_output_test_state(output->wlr_output, &state); |
141 | | - return ret; |
142 | | - } |
143 | | - |
144 | | - /* Apply output configuration */ |
145 | | - if (!wlr_output_commit_state(output->wlr_output, &state)) { |
146 | | - return false; |
147 | | - } |
148 | | - |
149 | | - if (head->state.enabled) { |
150 | | - output_layout_add(output, head->state.x, head->state.y); |
151 | | - } else { |
152 | | - output_layout_remove(output); |
153 | | - } |
154 | | - |
155 | | - return true; |
156 | | -} |
157 | | - |
158 | 135 | static void |
159 | 136 | handle_output_frame(struct wl_listener *listener, void *data) |
160 | 137 | { |
@@ -355,17 +332,63 @@ output_set_window_title(struct cg_output *output, const char *title) |
355 | 332 | static bool |
356 | 333 | output_config_apply(struct cg_server *server, struct wlr_output_configuration_v1 *config, bool test_only) |
357 | 334 | { |
358 | | - struct wlr_output_configuration_head_v1 *head; |
| 335 | + bool ok = false; |
359 | 336 |
|
| 337 | + size_t states_len; |
| 338 | + struct wlr_backend_output_state *states = wlr_output_configuration_v1_build_state(config, &states_len); |
| 339 | + if (states == NULL) { |
| 340 | + return false; |
| 341 | + } |
| 342 | + |
| 343 | + struct wlr_output_swapchain_manager swapchain_manager; |
| 344 | + wlr_output_swapchain_manager_init(&swapchain_manager, server->backend); |
| 345 | + |
| 346 | + ok = wlr_output_swapchain_manager_prepare(&swapchain_manager, states, states_len); |
| 347 | + if (!ok || test_only) { |
| 348 | + goto out; |
| 349 | + } |
| 350 | + |
| 351 | + for (size_t i = 0; i < states_len; i++) { |
| 352 | + struct wlr_backend_output_state *backend_state = &states[i]; |
| 353 | + struct cg_output *output = backend_state->output->data; |
| 354 | + |
| 355 | + struct wlr_swapchain *swapchain = |
| 356 | + wlr_output_swapchain_manager_get_swapchain(&swapchain_manager, backend_state->output); |
| 357 | + struct wlr_scene_output_state_options options = { |
| 358 | + .swapchain = swapchain, |
| 359 | + }; |
| 360 | + struct wlr_output_state *state = &backend_state->base; |
| 361 | + if (!wlr_scene_output_build_state(output->scene_output, state, &options)) { |
| 362 | + ok = false; |
| 363 | + goto out; |
| 364 | + } |
| 365 | + } |
| 366 | + |
| 367 | + ok = wlr_backend_commit(server->backend, states, states_len); |
| 368 | + if (!ok) { |
| 369 | + goto out; |
| 370 | + } |
| 371 | + |
| 372 | + wlr_output_swapchain_manager_apply(&swapchain_manager); |
| 373 | + |
| 374 | + struct wlr_output_configuration_head_v1 *head; |
360 | 375 | wl_list_for_each (head, &config->heads, link) { |
361 | 376 | struct cg_output *output = head->state.output->data; |
362 | 377 |
|
363 | | - if (!output_apply_config(output, head, test_only)) { |
364 | | - return false; |
| 378 | + if (head->state.enabled) { |
| 379 | + output_layout_add(output, head->state.x, head->state.y); |
| 380 | + } else { |
| 381 | + output_layout_remove(output); |
365 | 382 | } |
366 | 383 | } |
367 | 384 |
|
368 | | - return true; |
| 385 | +out: |
| 386 | + wlr_output_swapchain_manager_finish(&swapchain_manager); |
| 387 | + for (size_t i = 0; i < states_len; i++) { |
| 388 | + wlr_output_state_finish(&states[i].base); |
| 389 | + } |
| 390 | + free(states); |
| 391 | + return ok; |
369 | 392 | } |
370 | 393 |
|
371 | 394 | void |
|
0 commit comments