aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/transaction.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-29 08:29:11 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-29 08:29:11 +1000
commitb12f7be9071f085894b47950cc0e1fda2187d7e5 (patch)
treec2d50ea44c1857ec0c0132d9e73f7c32ab7fb91e /sway/desktop/transaction.c
parentMerge pull request #2526 from ianyfan/commands (diff)
downloadsway-b12f7be9071f085894b47950cc0e1fda2187d7e5.tar.gz
sway-b12f7be9071f085894b47950cc0e1fda2187d7e5.tar.zst
sway-b12f7be9071f085894b47950cc0e1fda2187d7e5.zip
Don't use bitfield to test for similar transactions
When there's multiple transactions in the queue, sway can take a shortcut by checking if they all operate on the same set of containers. If they do, it can skip all but the last transaction. The way we tested for transactions which used the same containers was to exclusive-or their con IDs together, but this has proved not only to be ineffective but also has the potential to make sway crash. This patch replaces the exclusive-or with a loop and container comparison.
Diffstat (limited to 'sway/desktop/transaction.c')
-rw-r--r--sway/desktop/transaction.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index c18529fb..1316a80d 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -22,7 +22,6 @@ struct sway_transaction {
22 list_t *instructions; // struct sway_transaction_instruction * 22 list_t *instructions; // struct sway_transaction_instruction *
23 size_t num_waiting; 23 size_t num_waiting;
24 size_t num_configures; 24 size_t num_configures;
25 uint32_t con_ids; // Bitwise XOR of view container IDs
26 struct timespec commit_time; 25 struct timespec commit_time;
27}; 26};
28 27
@@ -218,6 +217,22 @@ static void transaction_apply(struct sway_transaction *transaction) {
218 217
219static void transaction_commit(struct sway_transaction *transaction); 218static void transaction_commit(struct sway_transaction *transaction);
220 219
220// Return true if both transactions operate on the same containers
221static bool transaction_same_containers(struct sway_transaction *a,
222 struct sway_transaction *b) {
223 if (a->instructions->length != b->instructions->length) {
224 return false;
225 }
226 for (int i = 0; i < a->instructions->length; ++i) {
227 struct sway_transaction_instruction *a_inst = a->instructions->items[i];
228 struct sway_transaction_instruction *b_inst = b->instructions->items[i];
229 if (a_inst->container != b_inst->container) {
230 return false;
231 }
232 }
233 return true;
234}
235
221static void transaction_progress_queue() { 236static void transaction_progress_queue() {
222 if (!server.transactions->length) { 237 if (!server.transactions->length) {
223 return; 238 return;
@@ -242,7 +257,7 @@ static void transaction_progress_queue() {
242 while (server.transactions->length >= 2) { 257 while (server.transactions->length >= 2) {
243 struct sway_transaction *a = server.transactions->items[0]; 258 struct sway_transaction *a = server.transactions->items[0];
244 struct sway_transaction *b = server.transactions->items[1]; 259 struct sway_transaction *b = server.transactions->items[1];
245 if (a->con_ids == b->con_ids) { 260 if (transaction_same_containers(a, b)) {
246 list_del(server.transactions, 0); 261 list_del(server.transactions, 0);
247 transaction_destroy(a); 262 transaction_destroy(a);
248 } else { 263 } else {
@@ -294,7 +309,6 @@ static void transaction_commit(struct sway_transaction *transaction) {
294 instruction->state.view_width, 309 instruction->state.view_width,
295 instruction->state.view_height); 310 instruction->state.view_height);
296 ++transaction->num_waiting; 311 ++transaction->num_waiting;
297 transaction->con_ids ^= con->id;
298 312
299 // From here on we are rendering a saved buffer of the view, which 313 // From here on we are rendering a saved buffer of the view, which
300 // means we can send a frame done event to make the client redraw it 314 // means we can send a frame done event to make the client redraw it