diff options
Diffstat (limited to 'sway/desktop/transaction.c')
-rw-r--r-- | sway/desktop/transaction.c | 99 |
1 files changed, 32 insertions, 67 deletions
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index a449ffaa..c08730ce 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -43,12 +43,14 @@ struct sway_transaction_instruction { | |||
43 | struct sway_container *container; | 43 | struct sway_container *container; |
44 | struct sway_container_state state; | 44 | struct sway_container_state state; |
45 | uint32_t serial; | 45 | uint32_t serial; |
46 | bool ready; | ||
47 | }; | 46 | }; |
48 | 47 | ||
49 | static struct sway_transaction *transaction_create() { | 48 | static struct sway_transaction *transaction_create() { |
50 | struct sway_transaction *transaction = | 49 | struct sway_transaction *transaction = |
51 | calloc(1, sizeof(struct sway_transaction)); | 50 | calloc(1, sizeof(struct sway_transaction)); |
51 | if (!sway_assert(transaction, "Unable to allocate transaction")) { | ||
52 | return NULL; | ||
53 | } | ||
52 | transaction->instructions = create_list(); | 54 | transaction->instructions = create_list(); |
53 | if (server.debug_txn_timings) { | 55 | if (server.debug_txn_timings) { |
54 | clock_gettime(CLOCK_MONOTONIC, &transaction->create_time); | 56 | clock_gettime(CLOCK_MONOTONIC, &transaction->create_time); |
@@ -62,13 +64,11 @@ static void transaction_destroy(struct sway_transaction *transaction) { | |||
62 | struct sway_transaction_instruction *instruction = | 64 | struct sway_transaction_instruction *instruction = |
63 | transaction->instructions->items[i]; | 65 | transaction->instructions->items[i]; |
64 | struct sway_container *con = instruction->container; | 66 | struct sway_container *con = instruction->container; |
65 | for (int j = 0; j < con->instructions->length; ++j) { | 67 | con->ntxnrefs--; |
66 | if (con->instructions->items[j] == instruction) { | 68 | if (con->instruction == instruction) { |
67 | list_del(con->instructions, j); | 69 | con->instruction = NULL; |
68 | break; | ||
69 | } | ||
70 | } | 70 | } |
71 | if (con->destroying && !con->instructions->length) { | 71 | if (con->destroying && con->ntxnrefs == 0) { |
72 | container_free(con); | 72 | container_free(con); |
73 | } | 73 | } |
74 | free(instruction); | 74 | free(instruction); |
@@ -130,12 +130,16 @@ static void transaction_add_container(struct sway_transaction *transaction, | |||
130 | struct sway_container *container) { | 130 | struct sway_container *container) { |
131 | struct sway_transaction_instruction *instruction = | 131 | struct sway_transaction_instruction *instruction = |
132 | calloc(1, sizeof(struct sway_transaction_instruction)); | 132 | calloc(1, sizeof(struct sway_transaction_instruction)); |
133 | if (!sway_assert(instruction, "Unable to allocate instruction")) { | ||
134 | return; | ||
135 | } | ||
133 | instruction->transaction = transaction; | 136 | instruction->transaction = transaction; |
134 | instruction->container = container; | 137 | instruction->container = container; |
135 | 138 | ||
136 | copy_pending_state(container, &instruction->state); | 139 | copy_pending_state(container, &instruction->state); |
137 | 140 | ||
138 | list_add(transaction->instructions, instruction); | 141 | list_add(transaction->instructions, instruction); |
142 | container->ntxnrefs++; | ||
139 | } | 143 | } |
140 | 144 | ||
141 | /** | 145 | /** |
@@ -195,21 +199,11 @@ static void transaction_apply(struct sway_transaction *transaction) { | |||
195 | memcpy(&container->current, &instruction->state, | 199 | memcpy(&container->current, &instruction->state, |
196 | sizeof(struct sway_container_state)); | 200 | sizeof(struct sway_container_state)); |
197 | 201 | ||
198 | if (container->type == C_VIEW) { | 202 | if (container->type == C_VIEW && container->sway_view->saved_buffer) { |
199 | if (container->destroying) { | 203 | view_remove_saved_buffer(container->sway_view); |
200 | if (container->instructions->length == 1 && | ||
201 | container->sway_view->saved_buffer) { | ||
202 | view_remove_saved_buffer(container->sway_view); | ||
203 | } | ||
204 | } else { | ||
205 | if (container->sway_view->saved_buffer) { | ||
206 | view_remove_saved_buffer(container->sway_view); | ||
207 | } | ||
208 | if (container->instructions->length > 1) { | ||
209 | view_save_buffer(container->sway_view); | ||
210 | } | ||
211 | } | ||
212 | } | 204 | } |
205 | |||
206 | container->instruction = NULL; | ||
213 | } | 207 | } |
214 | } | 208 | } |
215 | 209 | ||
@@ -269,20 +263,8 @@ static bool should_configure(struct sway_container *con, | |||
269 | if (con->destroying) { | 263 | if (con->destroying) { |
270 | return false; | 264 | return false; |
271 | } | 265 | } |
272 | // The settled dimensions are what size the view will be once any pending | 266 | if (con->current.view_width == instruction->state.view_width && |
273 | // configures have applied (excluding the one we might be configuring now). | 267 | con->current.view_height == instruction->state.view_height) { |
274 | // If these match the dimensions that this transaction wants then we don't | ||
275 | // need to configure it. | ||
276 | int settled_width = con->current.view_width; | ||
277 | int settled_height = con->current.view_height; | ||
278 | if (con->instructions->length) { | ||
279 | struct sway_transaction_instruction *last_instruction = | ||
280 | con->instructions->items[con->instructions->length - 1]; | ||
281 | settled_width = last_instruction->state.view_width; | ||
282 | settled_height = last_instruction->state.view_height; | ||
283 | } | ||
284 | if (settled_width == instruction->state.view_width && | ||
285 | settled_height == instruction->state.view_height) { | ||
286 | return false; | 268 | return false; |
287 | } | 269 | } |
288 | return true; | 270 | return true; |
@@ -312,10 +294,10 @@ static void transaction_commit(struct sway_transaction *transaction) { | |||
312 | struct timespec when; | 294 | struct timespec when; |
313 | wlr_surface_send_frame_done(con->sway_view->surface, &when); | 295 | wlr_surface_send_frame_done(con->sway_view->surface, &when); |
314 | } | 296 | } |
315 | if (con->type == C_VIEW && !con->sway_view->saved_buffer) { | 297 | if (con->type == C_VIEW) { |
316 | view_save_buffer(con->sway_view); | 298 | view_save_buffer(con->sway_view); |
317 | } | 299 | } |
318 | list_add(con->instructions, instruction); | 300 | con->instruction = instruction; |
319 | } | 301 | } |
320 | transaction->num_configures = transaction->num_waiting; | 302 | transaction->num_configures = transaction->num_waiting; |
321 | if (server.debug_txn_timings) { | 303 | if (server.debug_txn_timings) { |
@@ -347,7 +329,6 @@ static void transaction_commit(struct sway_transaction *transaction) { | |||
347 | 329 | ||
348 | static void set_instruction_ready( | 330 | static void set_instruction_ready( |
349 | struct sway_transaction_instruction *instruction) { | 331 | struct sway_transaction_instruction *instruction) { |
350 | instruction->ready = true; | ||
351 | struct sway_transaction *transaction = instruction->transaction; | 332 | struct sway_transaction *transaction = instruction->transaction; |
352 | 333 | ||
353 | if (server.debug_txn_timings) { | 334 | if (server.debug_txn_timings) { |
@@ -371,44 +352,25 @@ static void set_instruction_ready( | |||
371 | wl_event_source_timer_update(transaction->timer, 0); | 352 | wl_event_source_timer_update(transaction->timer, 0); |
372 | } | 353 | } |
373 | } | 354 | } |
374 | } | ||
375 | 355 | ||
376 | /** | 356 | instruction->container->instruction = NULL; |
377 | * Mark all of the view's instructions as ready up to and including the | ||
378 | * instruction at the given index. This allows the view to skip a configure. | ||
379 | */ | ||
380 | static void set_instructions_ready(struct sway_view *view, int index) { | ||
381 | for (int i = 0; i <= index; ++i) { | ||
382 | struct sway_transaction_instruction *instruction = | ||
383 | view->swayc->instructions->items[i]; | ||
384 | if (!instruction->ready) { | ||
385 | set_instruction_ready(instruction); | ||
386 | } | ||
387 | } | ||
388 | transaction_progress_queue(); | 357 | transaction_progress_queue(); |
389 | } | 358 | } |
390 | 359 | ||
391 | void transaction_notify_view_ready(struct sway_view *view, uint32_t serial) { | 360 | void transaction_notify_view_ready_by_serial(struct sway_view *view, |
392 | for (int i = 0; i < view->swayc->instructions->length; ++i) { | 361 | uint32_t serial) { |
393 | struct sway_transaction_instruction *instruction = | 362 | struct sway_transaction_instruction *instruction = view->swayc->instruction; |
394 | view->swayc->instructions->items[i]; | 363 | if (view->swayc->instruction->serial == serial) { |
395 | if (instruction->serial == serial && !instruction->ready) { | 364 | set_instruction_ready(instruction); |
396 | set_instructions_ready(view, i); | ||
397 | return; | ||
398 | } | ||
399 | } | 365 | } |
400 | } | 366 | } |
401 | 367 | ||
402 | void transaction_notify_view_ready_by_size(struct sway_view *view, | 368 | void transaction_notify_view_ready_by_size(struct sway_view *view, |
403 | int width, int height) { | 369 | int width, int height) { |
404 | for (int i = 0; i < view->swayc->instructions->length; ++i) { | 370 | struct sway_transaction_instruction *instruction = view->swayc->instruction; |
405 | struct sway_transaction_instruction *instruction = | 371 | if (instruction->state.view_width == width && |
406 | view->swayc->instructions->items[i]; | 372 | instruction->state.view_height == height) { |
407 | if (!instruction->ready && instruction->state.view_width == width && | 373 | set_instruction_ready(instruction); |
408 | instruction->state.view_height == height) { | ||
409 | set_instructions_ready(view, i); | ||
410 | return; | ||
411 | } | ||
412 | } | 374 | } |
413 | } | 375 | } |
414 | 376 | ||
@@ -417,6 +379,9 @@ void transaction_commit_dirty(void) { | |||
417 | return; | 379 | return; |
418 | } | 380 | } |
419 | struct sway_transaction *transaction = transaction_create(); | 381 | struct sway_transaction *transaction = transaction_create(); |
382 | if (!transaction) { | ||
383 | return; | ||
384 | } | ||
420 | for (int i = 0; i < server.dirty_containers->length; ++i) { | 385 | for (int i = 0; i < server.dirty_containers->length; ++i) { |
421 | struct sway_container *container = server.dirty_containers->items[i]; | 386 | struct sway_container *container = server.dirty_containers->items[i]; |
422 | transaction_add_container(transaction, container); | 387 | transaction_add_container(transaction, container); |