aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/transaction.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-15 10:03:55 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-15 10:03:55 +1000
commitc3ef36d6b5d36f783f41b8860cee321b652f91e3 (patch)
tree4496de9473943b65e0d871b498176b820fea8e7b /sway/desktop/transaction.c
parentMerge pull request #2445 from RyanDwyer/resize-tiling-via-cursor (diff)
downloadsway-c3ef36d6b5d36f783f41b8860cee321b652f91e3.tar.gz
sway-c3ef36d6b5d36f783f41b8860cee321b652f91e3.tar.zst
sway-c3ef36d6b5d36f783f41b8860cee321b652f91e3.zip
Simplify transactions
Commit 4b8e3a885be74c588291c51f798de80bd81a92db makes it so only one transaction is committed (ie. configures sent) at a time. This commit removes the now-unnecessary code which was used to support concurrent committed transactions. * Instead of containers storing a list of instructions which they've been sent, it now stores a single instruction. * Containers now have an ntxnrefs property. Previously we knew how many references there were by the length of the instruction list. * Instructions no longer need a ready property. It was used to avoid marking an instruction ready twice when they were in a list, but this is now avoided because there is only one instruction and we nullify the container->instruction pointer when it's ready. * When a transaction applies, we no longer need to consider releasing and resaving the surface, as we know there are no other committed transactions. * transaction_notify_view_ready has been renamed to view_notify_view_ready_by_serial to make it consistent with transaction_notify_view_ready_by_size. * Out-of-memory checks have been added when creating transactions and instructions.
Diffstat (limited to 'sway/desktop/transaction.c')
-rw-r--r--sway/desktop/transaction.c99
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
49static struct sway_transaction *transaction_create() { 48static 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
348static void set_instruction_ready( 330static 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 */
380static 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
391void transaction_notify_view_ready(struct sway_view *view, uint32_t serial) { 360void 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
402void transaction_notify_view_ready_by_size(struct sway_view *view, 368void 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);