diff options
-rw-r--r-- | include/sway/desktop/transaction.h | 13 | ||||
-rw-r--r-- | include/sway/tree/view.h | 7 | ||||
-rw-r--r-- | sway/desktop/render.c | 16 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 51 | ||||
-rw-r--r-- | sway/tree/view.c | 20 |
5 files changed, 46 insertions, 61 deletions
diff --git a/include/sway/desktop/transaction.h b/include/sway/desktop/transaction.h index cee4afed..56361d94 100644 --- a/include/sway/desktop/transaction.h +++ b/include/sway/desktop/transaction.h | |||
@@ -42,17 +42,4 @@ void transaction_notify_view_ready(struct sway_view *view, uint32_t serial); | |||
42 | void transaction_notify_view_ready_by_size(struct sway_view *view, | 42 | void transaction_notify_view_ready_by_size(struct sway_view *view, |
43 | int width, int height); | 43 | int width, int height); |
44 | 44 | ||
45 | /** | ||
46 | * Get the saved texture that should be rendered for a view. | ||
47 | * | ||
48 | * The addresses pointed at by the width and height pointers will be populated | ||
49 | * with the surface's dimensions, which may be different to the texture's | ||
50 | * dimensions if output scaling is used. | ||
51 | * | ||
52 | * This function should only be called if it is known that the view has | ||
53 | * instructions. | ||
54 | */ | ||
55 | struct wlr_texture *transaction_get_saved_texture(struct sway_view *view, | ||
56 | int *width, int *height); | ||
57 | |||
58 | #endif | 45 | #endif |
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 0152ed55..0f9b0bb2 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -82,6 +82,9 @@ struct sway_view { | |||
82 | bool allow_request_urgent; | 82 | bool allow_request_urgent; |
83 | struct wl_event_source *urgent_timer; | 83 | struct wl_event_source *urgent_timer; |
84 | 84 | ||
85 | struct wlr_buffer *saved_buffer; | ||
86 | int saved_buffer_width, saved_buffer_height; | ||
87 | |||
85 | bool destroying; | 88 | bool destroying; |
86 | 89 | ||
87 | list_t *executed_criteria; // struct criteria * | 90 | list_t *executed_criteria; // struct criteria * |
@@ -323,4 +326,8 @@ void view_set_urgent(struct sway_view *view, bool enable); | |||
323 | 326 | ||
324 | bool view_is_urgent(struct sway_view *view); | 327 | bool view_is_urgent(struct sway_view *view); |
325 | 328 | ||
329 | void view_remove_saved_buffer(struct sway_view *view); | ||
330 | |||
331 | void view_save_buffer(struct sway_view *view); | ||
332 | |||
326 | #endif | 333 | #endif |
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index f25055b8..f0e47c95 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -199,17 +199,14 @@ static void render_saved_view(struct sway_view *view, | |||
199 | struct sway_output *output, pixman_region32_t *damage, float alpha) { | 199 | struct sway_output *output, pixman_region32_t *damage, float alpha) { |
200 | struct wlr_output *wlr_output = output->wlr_output; | 200 | struct wlr_output *wlr_output = output->wlr_output; |
201 | 201 | ||
202 | int width, height; | 202 | if (!view->saved_buffer || !view->saved_buffer->texture) { |
203 | struct wlr_texture *texture = | ||
204 | transaction_get_saved_texture(view, &width, &height); | ||
205 | if (!texture) { | ||
206 | return; | 203 | return; |
207 | } | 204 | } |
208 | struct wlr_box box = { | 205 | struct wlr_box box = { |
209 | .x = view->swayc->current.view_x - output->swayc->current.swayc_x, | 206 | .x = view->swayc->current.view_x - output->swayc->current.swayc_x, |
210 | .y = view->swayc->current.view_y - output->swayc->current.swayc_y, | 207 | .y = view->swayc->current.view_y - output->swayc->current.swayc_y, |
211 | .width = width, | 208 | .width = view->saved_buffer_width, |
212 | .height = height, | 209 | .height = view->saved_buffer_height, |
213 | }; | 210 | }; |
214 | 211 | ||
215 | struct wlr_box output_box = { | 212 | struct wlr_box output_box = { |
@@ -229,7 +226,8 @@ static void render_saved_view(struct sway_view *view, | |||
229 | wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0, | 226 | wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0, |
230 | wlr_output->transform_matrix); | 227 | wlr_output->transform_matrix); |
231 | 228 | ||
232 | render_texture(wlr_output, damage, texture, &box, matrix, alpha); | 229 | render_texture(wlr_output, damage, view->saved_buffer->texture, |
230 | &box, matrix, alpha); | ||
233 | } | 231 | } |
234 | 232 | ||
235 | /** | 233 | /** |
@@ -238,7 +236,7 @@ static void render_saved_view(struct sway_view *view, | |||
238 | static void render_view(struct sway_output *output, pixman_region32_t *damage, | 236 | static void render_view(struct sway_output *output, pixman_region32_t *damage, |
239 | struct sway_container *con, struct border_colors *colors) { | 237 | struct sway_container *con, struct border_colors *colors) { |
240 | struct sway_view *view = con->sway_view; | 238 | struct sway_view *view = con->sway_view; |
241 | if (view->swayc->instructions->length) { | 239 | if (view->saved_buffer) { |
242 | render_saved_view(view, output, damage, view->swayc->alpha); | 240 | render_saved_view(view, output, damage, view->swayc->alpha); |
243 | } else { | 241 | } else { |
244 | render_view_surfaces(view, output, damage, view->swayc->alpha); | 242 | render_view_surfaces(view, output, damage, view->swayc->alpha); |
@@ -841,7 +839,7 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
841 | 839 | ||
842 | // TODO: handle views smaller than the output | 840 | // TODO: handle views smaller than the output |
843 | if (fullscreen_con->type == C_VIEW) { | 841 | if (fullscreen_con->type == C_VIEW) { |
844 | if (fullscreen_con->instructions->length) { | 842 | if (fullscreen_con->sway_view->saved_buffer) { |
845 | render_saved_view(fullscreen_con->sway_view, | 843 | render_saved_view(fullscreen_con->sway_view, |
846 | output, damage, 1.0f); | 844 | output, damage, 1.0f); |
847 | } else { | 845 | } else { |
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 7975366e..94070363 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -41,8 +41,6 @@ struct sway_transaction_instruction { | |||
41 | struct sway_transaction *transaction; | 41 | struct sway_transaction *transaction; |
42 | struct sway_container *container; | 42 | struct sway_container *container; |
43 | struct sway_container_state state; | 43 | struct sway_container_state state; |
44 | struct wlr_buffer *saved_buffer; | ||
45 | int saved_buffer_width, saved_buffer_height; | ||
46 | uint32_t serial; | 44 | uint32_t serial; |
47 | bool ready; | 45 | bool ready; |
48 | }; | 46 | }; |
@@ -57,27 +55,6 @@ static struct sway_transaction *transaction_create() { | |||
57 | return transaction; | 55 | return transaction; |
58 | } | 56 | } |
59 | 57 | ||
60 | static void remove_saved_view_buffer( | ||
61 | struct sway_transaction_instruction *instruction) { | ||
62 | if (instruction->saved_buffer) { | ||
63 | wlr_buffer_unref(instruction->saved_buffer); | ||
64 | instruction->saved_buffer = NULL; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | static void save_view_buffer(struct sway_view *view, | ||
69 | struct sway_transaction_instruction *instruction) { | ||
70 | if (!sway_assert(instruction->saved_buffer == NULL, | ||
71 | "Didn't expect instruction to have a saved buffer already")) { | ||
72 | remove_saved_view_buffer(instruction); | ||
73 | } | ||
74 | if (view->surface && wlr_surface_has_buffer(view->surface)) { | ||
75 | instruction->saved_buffer = wlr_buffer_ref(view->surface->buffer); | ||
76 | instruction->saved_buffer_width = view->surface->current.width; | ||
77 | instruction->saved_buffer_height = view->surface->current.height; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | static void transaction_destroy(struct sway_transaction *transaction) { | 58 | static void transaction_destroy(struct sway_transaction *transaction) { |
82 | // Free instructions | 59 | // Free instructions |
83 | for (int i = 0; i < transaction->instructions->length; ++i) { | 60 | for (int i = 0; i < transaction->instructions->length; ++i) { |
@@ -93,7 +70,6 @@ static void transaction_destroy(struct sway_transaction *transaction) { | |||
93 | if (con->destroying && !con->instructions->length) { | 70 | if (con->destroying && !con->instructions->length) { |
94 | container_free(con); | 71 | container_free(con); |
95 | } | 72 | } |
96 | remove_saved_view_buffer(instruction); | ||
97 | free(instruction); | 73 | free(instruction); |
98 | } | 74 | } |
99 | list_free(transaction->instructions); | 75 | list_free(transaction->instructions); |
@@ -158,9 +134,6 @@ static void transaction_add_container(struct sway_transaction *transaction, | |||
158 | 134 | ||
159 | copy_pending_state(container, &instruction->state); | 135 | copy_pending_state(container, &instruction->state); |
160 | 136 | ||
161 | if (container->type == C_VIEW) { | ||
162 | save_view_buffer(container->sway_view, instruction); | ||
163 | } | ||
164 | list_add(transaction->instructions, instruction); | 137 | list_add(transaction->instructions, instruction); |
165 | } | 138 | } |
166 | 139 | ||
@@ -220,6 +193,15 @@ static void transaction_apply(struct sway_transaction *transaction) { | |||
220 | 193 | ||
221 | memcpy(&container->current, &instruction->state, | 194 | memcpy(&container->current, &instruction->state, |
222 | sizeof(struct sway_container_state)); | 195 | sizeof(struct sway_container_state)); |
196 | |||
197 | if (container->type == C_VIEW) { | ||
198 | if (container->sway_view->saved_buffer) { | ||
199 | view_remove_saved_buffer(container->sway_view); | ||
200 | } | ||
201 | if (container->instructions->length > 1) { | ||
202 | view_save_buffer(container->sway_view); | ||
203 | } | ||
204 | } | ||
223 | } | 205 | } |
224 | } | 206 | } |
225 | 207 | ||
@@ -294,6 +276,9 @@ static void transaction_commit(struct sway_transaction *transaction) { | |||
294 | // mapping and its default geometry doesn't intersect an output. | 276 | // mapping and its default geometry doesn't intersect an output. |
295 | struct timespec when; | 277 | struct timespec when; |
296 | wlr_surface_send_frame_done(con->sway_view->surface, &when); | 278 | wlr_surface_send_frame_done(con->sway_view->surface, &when); |
279 | if (!con->sway_view->saved_buffer) { | ||
280 | view_save_buffer(con->sway_view); | ||
281 | } | ||
297 | } | 282 | } |
298 | list_add(con->instructions, instruction); | 283 | list_add(con->instructions, instruction); |
299 | } | 284 | } |
@@ -400,18 +385,6 @@ void transaction_notify_view_ready_by_size(struct sway_view *view, | |||
400 | } | 385 | } |
401 | } | 386 | } |
402 | 387 | ||
403 | struct wlr_texture *transaction_get_saved_texture(struct sway_view *view, | ||
404 | int *width, int *height) { | ||
405 | struct sway_transaction_instruction *instruction = | ||
406 | view->swayc->instructions->items[0]; | ||
407 | if (!instruction->saved_buffer) { | ||
408 | return NULL; | ||
409 | } | ||
410 | *width = instruction->saved_buffer_width; | ||
411 | *height = instruction->saved_buffer_height; | ||
412 | return instruction->saved_buffer->texture; | ||
413 | } | ||
414 | |||
415 | void transaction_commit_dirty(void) { | 388 | void transaction_commit_dirty(void) { |
416 | if (!server.dirty_containers->length) { | 389 | if (!server.dirty_containers->length) { |
417 | return; | 390 | return; |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 8f54cc11..0dbd3812 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <wayland-server.h> | 3 | #include <wayland-server.h> |
4 | #include <wlr/render/wlr_renderer.h> | 4 | #include <wlr/render/wlr_renderer.h> |
5 | #include <wlr/types/wlr_buffer.h> | ||
5 | #include <wlr/types/wlr_output_layout.h> | 6 | #include <wlr/types/wlr_output_layout.h> |
6 | #include "config.h" | 7 | #include "config.h" |
7 | #ifdef HAVE_XWAYLAND | 8 | #ifdef HAVE_XWAYLAND |
@@ -1070,3 +1071,22 @@ void view_set_urgent(struct sway_view *view, bool enable) { | |||
1070 | bool view_is_urgent(struct sway_view *view) { | 1071 | bool view_is_urgent(struct sway_view *view) { |
1071 | return view->urgent.tv_sec || view->urgent.tv_nsec; | 1072 | return view->urgent.tv_sec || view->urgent.tv_nsec; |
1072 | } | 1073 | } |
1074 | |||
1075 | void view_remove_saved_buffer(struct sway_view *view) { | ||
1076 | if (!sway_assert(view->saved_buffer, "Expected a saved buffer")) { | ||
1077 | return; | ||
1078 | } | ||
1079 | wlr_buffer_unref(view->saved_buffer); | ||
1080 | view->saved_buffer = NULL; | ||
1081 | } | ||
1082 | |||
1083 | void view_save_buffer(struct sway_view *view) { | ||
1084 | if (!sway_assert(!view->saved_buffer, "Didn't expect saved buffer")) { | ||
1085 | view_remove_saved_buffer(view); | ||
1086 | } | ||
1087 | if (view->surface && wlr_surface_has_buffer(view->surface)) { | ||
1088 | view->saved_buffer = wlr_buffer_ref(view->surface->buffer); | ||
1089 | view->saved_buffer_width = view->surface->current.width; | ||
1090 | view->saved_buffer_height = view->surface->current.height; | ||
1091 | } | ||
1092 | } | ||