diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-08-19 10:29:29 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-19 10:29:29 -0400 |
commit | 9f913614cad6d157bbf33b012093dda6f3e7665e (patch) | |
tree | fd63244ea01baecc425fb8f3b159975beb5a31e5 | |
parent | Merge pull request #2487 from RyanDwyer/workspace-floating-list (diff) | |
parent | Use enum for damage debug options (diff) | |
download | sway-9f913614cad6d157bbf33b012093dda6f3e7665e.tar.gz sway-9f913614cad6d157bbf33b012093dda6f3e7665e.tar.zst sway-9f913614cad6d157bbf33b012093dda6f3e7665e.zip |
Merge pull request #2478 from RyanDwyer/standardise-debug
Standardise debug variables
-rw-r--r-- | include/sway/debug.h | 23 | ||||
-rw-r--r-- | include/sway/server.h | 3 | ||||
-rw-r--r-- | sway/debug-tree.c | 8 | ||||
-rw-r--r-- | sway/desktop/render.c | 26 | ||||
-rw-r--r-- | sway/desktop/transaction.c | 61 | ||||
-rw-r--r-- | sway/main.c | 20 | ||||
-rw-r--r-- | sway/server.c | 7 |
7 files changed, 68 insertions, 80 deletions
diff --git a/include/sway/debug.h b/include/sway/debug.h index 38d4eccd..bf3a5f6d 100644 --- a/include/sway/debug.h +++ b/include/sway/debug.h | |||
@@ -1,15 +1,22 @@ | |||
1 | #ifndef SWAY_DEBUG_H | 1 | #ifndef SWAY_DEBUG_H |
2 | #define SWAY_DEBUG_H | 2 | #define SWAY_DEBUG_H |
3 | #include <stdbool.h> | ||
3 | 4 | ||
4 | // Tree | 5 | struct sway_debug { |
5 | extern bool enable_debug_tree; | 6 | bool noatomic; // Ignore atomic layout updates |
6 | void update_debug_tree(); | 7 | bool render_tree; // Render the tree overlay |
8 | bool txn_timings; // Log verbose messages about transactions | ||
9 | bool txn_wait; // Always wait for the timeout before applying | ||
10 | |||
11 | enum { | ||
12 | DAMAGE_DEFAULT, // Default behaviour | ||
13 | DAMAGE_HIGHLIGHT, // Highlight regions of the screen being damaged | ||
14 | DAMAGE_RERENDER, // Render the full output when any damage occurs | ||
15 | } damage; | ||
16 | }; | ||
7 | 17 | ||
8 | // Damage | 18 | extern struct sway_debug debug; |
9 | extern const char *damage_debug; | ||
10 | 19 | ||
11 | // Transactions | 20 | void update_debug_tree(); |
12 | extern int txn_timeout_ms; | ||
13 | extern bool txn_debug; | ||
14 | 21 | ||
15 | #endif | 22 | #endif |
diff --git a/include/sway/server.h b/include/sway/server.h index b93584b6..1e20f2c8 100644 --- a/include/sway/server.h +++ b/include/sway/server.h | |||
@@ -54,8 +54,7 @@ struct sway_server { | |||
54 | struct wl_listener server_decoration; | 54 | struct wl_listener server_decoration; |
55 | struct wl_list decorations; // sway_server_decoration::link | 55 | struct wl_list decorations; // sway_server_decoration::link |
56 | 56 | ||
57 | bool debug_txn_timings; | 57 | size_t txn_timeout_ms; |
58 | |||
59 | list_t *transactions; | 58 | list_t *transactions; |
60 | list_t *dirty_containers; | 59 | list_t *dirty_containers; |
61 | }; | 60 | }; |
diff --git a/sway/debug-tree.c b/sway/debug-tree.c index 0cb499e7..ea0826b9 100644 --- a/sway/debug-tree.c +++ b/sway/debug-tree.c | |||
@@ -3,8 +3,10 @@ | |||
3 | #include <wlr/render/wlr_texture.h> | 3 | #include <wlr/render/wlr_texture.h> |
4 | #include <wlr/util/log.h> | 4 | #include <wlr/util/log.h> |
5 | #include "config.h" | 5 | #include "config.h" |
6 | #include "sway/debug.h" | ||
6 | #include "sway/input/input-manager.h" | 7 | #include "sway/input/input-manager.h" |
7 | #include "sway/input/seat.h" | 8 | #include "sway/input/seat.h" |
9 | #include "sway/output.h" | ||
8 | #include "sway/server.h" | 10 | #include "sway/server.h" |
9 | #include "sway/tree/container.h" | 11 | #include "sway/tree/container.h" |
10 | #include "sway/tree/layout.h" | 12 | #include "sway/tree/layout.h" |
@@ -12,6 +14,8 @@ | |||
12 | #include "config.h" | 14 | #include "config.h" |
13 | #include "pango.h" | 15 | #include "pango.h" |
14 | 16 | ||
17 | struct sway_debug debug; | ||
18 | |||
15 | static const char *layout_to_str(enum sway_container_layout layout) { | 19 | static const char *layout_to_str(enum sway_container_layout layout) { |
16 | switch (layout) { | 20 | switch (layout) { |
17 | case L_HORIZ: | 21 | case L_HORIZ: |
@@ -67,10 +71,8 @@ static int draw_container(cairo_t *cairo, struct sway_container *container, | |||
67 | return height; | 71 | return height; |
68 | } | 72 | } |
69 | 73 | ||
70 | bool enable_debug_tree = false; | ||
71 | |||
72 | void update_debug_tree() { | 74 | void update_debug_tree() { |
73 | if (!enable_debug_tree) { | 75 | if (!debug.render_tree) { |
74 | return; | 76 | return; |
75 | } | 77 | } |
76 | 78 | ||
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index aa70903e..5cf8abc0 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -813,8 +813,6 @@ static void render_floating(struct sway_output *soutput, | |||
813 | } | 813 | } |
814 | } | 814 | } |
815 | 815 | ||
816 | const char *damage_debug = NULL; | ||
817 | |||
818 | void output_render(struct sway_output *output, struct timespec *when, | 816 | void output_render(struct sway_output *output, struct timespec *when, |
819 | pixman_region32_t *damage) { | 817 | pixman_region32_t *damage) { |
820 | struct wlr_output *wlr_output = output->wlr_output; | 818 | struct wlr_output *wlr_output = output->wlr_output; |
@@ -828,21 +826,17 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
828 | 826 | ||
829 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); | 827 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); |
830 | 828 | ||
831 | bool damage_whole_before_swap = false; | ||
832 | if (!pixman_region32_not_empty(damage)) { | 829 | if (!pixman_region32_not_empty(damage)) { |
833 | // Output isn't damaged but needs buffer swap | 830 | // Output isn't damaged but needs buffer swap |
834 | goto renderer_end; | 831 | goto renderer_end; |
835 | } | 832 | } |
836 | 833 | ||
837 | if (damage_debug != NULL) { | 834 | if (debug.damage == DAMAGE_HIGHLIGHT) { |
838 | if (strcmp(damage_debug, "highlight") == 0) { | 835 | wlr_renderer_clear(renderer, (float[]){1, 1, 0, 1}); |
839 | wlr_renderer_clear(renderer, (float[]){1, 1, 0, 1}); | 836 | } else if (debug.damage == DAMAGE_RERENDER) { |
840 | damage_whole_before_swap = true; | 837 | int width, height; |
841 | } else if (strcmp(damage_debug, "rerender") == 0) { | 838 | wlr_output_transformed_resolution(wlr_output, &width, &height); |
842 | int width, height; | 839 | pixman_region32_union_rect(damage, damage, 0, 0, width, height); |
843 | wlr_output_transformed_resolution(wlr_output, &width, &height); | ||
844 | pixman_region32_union_rect(damage, damage, 0, 0, width, height); | ||
845 | } | ||
846 | } | 840 | } |
847 | 841 | ||
848 | struct sway_container *workspace = output_get_active_workspace(output); | 842 | struct sway_container *workspace = output_get_active_workspace(output); |
@@ -916,12 +910,12 @@ render_overlay: | |||
916 | render_drag_icons(output, damage, &root_container.sway_root->drag_icons); | 910 | render_drag_icons(output, damage, &root_container.sway_root->drag_icons); |
917 | 911 | ||
918 | renderer_end: | 912 | renderer_end: |
919 | if (root_container.sway_root->debug_tree) { | 913 | if (debug.render_tree) { |
914 | wlr_renderer_scissor(renderer, NULL); | ||
920 | wlr_render_texture(renderer, root_container.sway_root->debug_tree, | 915 | wlr_render_texture(renderer, root_container.sway_root->debug_tree, |
921 | wlr_output->transform_matrix, 0, 0, 1); | 916 | wlr_output->transform_matrix, 0, 40, 1); |
922 | } | 917 | } |
923 | 918 | if (debug.damage == DAMAGE_HIGHLIGHT) { | |
924 | if (damage_whole_before_swap || root_container.sway_root->debug_tree) { | ||
925 | int width, height; | 919 | int width, height; |
926 | wlr_output_transformed_resolution(wlr_output, &width, &height); | 920 | wlr_output_transformed_resolution(wlr_output, &width, &height); |
927 | pixman_region32_union_rect(damage, damage, 0, 0, width, height); | 921 | pixman_region32_union_rect(damage, damage, 0, 0, width, height); |
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 692fb447..d77a2afd 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <errno.h> | 2 | #include <errno.h> |
3 | #include <limits.h> | ||
3 | #include <stdbool.h> | 4 | #include <stdbool.h> |
4 | #include <stdlib.h> | 5 | #include <stdlib.h> |
5 | #include <string.h> | 6 | #include <string.h> |
@@ -16,26 +17,12 @@ | |||
16 | #include "list.h" | 17 | #include "list.h" |
17 | #include "log.h" | 18 | #include "log.h" |
18 | 19 | ||
19 | /** | ||
20 | * How long we should wait for views to respond to the configure before giving | ||
21 | * up and applying the transaction anyway. | ||
22 | */ | ||
23 | int txn_timeout_ms = 200; | ||
24 | |||
25 | /** | ||
26 | * If enabled, sway will always wait for the transaction timeout before | ||
27 | * applying it, rather than applying it when the views are ready. This allows us | ||
28 | * to observe the rendered state while a transaction is in progress. | ||
29 | */ | ||
30 | bool txn_debug = false; | ||
31 | |||
32 | struct sway_transaction { | 20 | struct sway_transaction { |
33 | struct wl_event_source *timer; | 21 | struct wl_event_source *timer; |
34 | list_t *instructions; // struct sway_transaction_instruction * | 22 | list_t *instructions; // struct sway_transaction_instruction * |
35 | size_t num_waiting; | 23 | size_t num_waiting; |
36 | size_t num_configures; | 24 | size_t num_configures; |
37 | uint32_t con_ids; // Bitwise XOR of view container IDs | 25 | uint32_t con_ids; // Bitwise XOR of view container IDs |
38 | struct timespec create_time; | ||
39 | struct timespec commit_time; | 26 | struct timespec commit_time; |
40 | }; | 27 | }; |
41 | 28 | ||
@@ -53,9 +40,6 @@ static struct sway_transaction *transaction_create() { | |||
53 | return NULL; | 40 | return NULL; |
54 | } | 41 | } |
55 | transaction->instructions = create_list(); | 42 | transaction->instructions = create_list(); |
56 | if (server.debug_txn_timings) { | ||
57 | clock_gettime(CLOCK_MONOTONIC, &transaction->create_time); | ||
58 | } | ||
59 | return transaction; | 43 | return transaction; |
60 | } | 44 | } |
61 | 45 | ||
@@ -150,19 +134,14 @@ static void transaction_add_container(struct sway_transaction *transaction, | |||
150 | */ | 134 | */ |
151 | static void transaction_apply(struct sway_transaction *transaction) { | 135 | static void transaction_apply(struct sway_transaction *transaction) { |
152 | wlr_log(WLR_DEBUG, "Applying transaction %p", transaction); | 136 | wlr_log(WLR_DEBUG, "Applying transaction %p", transaction); |
153 | if (server.debug_txn_timings) { | 137 | if (debug.txn_timings) { |
154 | struct timespec now; | 138 | struct timespec now; |
155 | clock_gettime(CLOCK_MONOTONIC, &now); | 139 | clock_gettime(CLOCK_MONOTONIC, &now); |
156 | struct timespec *create = &transaction->create_time; | ||
157 | struct timespec *commit = &transaction->commit_time; | 140 | struct timespec *commit = &transaction->commit_time; |
158 | float ms_arranging = (commit->tv_sec - create->tv_sec) * 1000 + | 141 | float ms = (now.tv_sec - commit->tv_sec) * 1000 + |
159 | (commit->tv_nsec - create->tv_nsec) / 1000000.0; | ||
160 | float ms_waiting = (now.tv_sec - commit->tv_sec) * 1000 + | ||
161 | (now.tv_nsec - commit->tv_nsec) / 1000000.0; | 142 | (now.tv_nsec - commit->tv_nsec) / 1000000.0; |
162 | float ms_total = ms_arranging + ms_waiting; | 143 | wlr_log(WLR_DEBUG, "Transaction %p: %.1fms waiting " |
163 | wlr_log(WLR_DEBUG, "Transaction %p: %.1fms arranging, %.1fms waiting, " | 144 | "(%.1f frames if 60Hz)", transaction, ms, ms / (1000.0f / 60)); |
164 | "%.1fms total (%.1f frames if 60Hz)", transaction, | ||
165 | ms_arranging, ms_waiting, ms_total, ms_total / (1000.0f / 60)); | ||
166 | } | 145 | } |
167 | 146 | ||
168 | // Apply the instruction state to the container's current state | 147 | // Apply the instruction state to the container's current state |
@@ -312,25 +291,30 @@ static void transaction_commit(struct sway_transaction *transaction) { | |||
312 | con->instruction = instruction; | 291 | con->instruction = instruction; |
313 | } | 292 | } |
314 | transaction->num_configures = transaction->num_waiting; | 293 | transaction->num_configures = transaction->num_waiting; |
315 | if (server.debug_txn_timings) { | 294 | if (debug.txn_timings) { |
316 | clock_gettime(CLOCK_MONOTONIC, &transaction->commit_time); | 295 | clock_gettime(CLOCK_MONOTONIC, &transaction->commit_time); |
317 | } | 296 | } |
297 | if (debug.noatomic) { | ||
298 | transaction->num_waiting = 0; | ||
299 | } else if (debug.txn_wait) { | ||
300 | // Force the transaction to time out even if all views are ready. | ||
301 | // We do this by inflating the waiting counter. | ||
302 | transaction->num_waiting += 1000000; | ||
303 | } | ||
318 | 304 | ||
319 | if (transaction->num_waiting) { | 305 | if (transaction->num_waiting) { |
320 | // Set up a timer which the views must respond within | 306 | // Set up a timer which the views must respond within |
321 | transaction->timer = wl_event_loop_add_timer(server.wl_event_loop, | 307 | transaction->timer = wl_event_loop_add_timer(server.wl_event_loop, |
322 | handle_timeout, transaction); | 308 | handle_timeout, transaction); |
323 | if (transaction->timer) { | 309 | if (transaction->timer) { |
324 | wl_event_source_timer_update(transaction->timer, txn_timeout_ms); | 310 | wl_event_source_timer_update(transaction->timer, |
311 | server.txn_timeout_ms); | ||
325 | } else { | 312 | } else { |
326 | wlr_log(WLR_ERROR, "Unable to create transaction timer (%s). " | 313 | wlr_log(WLR_ERROR, "Unable to create transaction timer (%s). " |
327 | "Some imperfect frames might be rendered.", | 314 | "Some imperfect frames might be rendered.", |
328 | strerror(errno)); | 315 | strerror(errno)); |
329 | handle_timeout(transaction); | 316 | transaction->num_waiting = 0; |
330 | } | 317 | } |
331 | } else { | ||
332 | wlr_log(WLR_DEBUG, | ||
333 | "Transaction %p has nothing to wait for", transaction); | ||
334 | } | 318 | } |
335 | 319 | ||
336 | // The debug tree shows the pending/live tree. Here is a good place to | 320 | // The debug tree shows the pending/live tree. Here is a good place to |
@@ -343,7 +327,7 @@ static void set_instruction_ready( | |||
343 | struct sway_transaction_instruction *instruction) { | 327 | struct sway_transaction_instruction *instruction) { |
344 | struct sway_transaction *transaction = instruction->transaction; | 328 | struct sway_transaction *transaction = instruction->transaction; |
345 | 329 | ||
346 | if (server.debug_txn_timings) { | 330 | if (debug.txn_timings) { |
347 | struct timespec now; | 331 | struct timespec now; |
348 | clock_gettime(CLOCK_MONOTONIC, &now); | 332 | clock_gettime(CLOCK_MONOTONIC, &now); |
349 | struct timespec *start = &transaction->commit_time; | 333 | struct timespec *start = &transaction->commit_time; |
@@ -354,21 +338,16 @@ static void set_instruction_ready( | |||
354 | transaction->num_configures - transaction->num_waiting + 1, | 338 | transaction->num_configures - transaction->num_waiting + 1, |
355 | transaction->num_configures, ms, | 339 | transaction->num_configures, ms, |
356 | instruction->container->name); | 340 | instruction->container->name); |
357 | |||
358 | } | 341 | } |
359 | 342 | ||
360 | // If the transaction has timed out then its num_waiting will be 0 already. | 343 | // If the transaction has timed out then its num_waiting will be 0 already. |
361 | if (transaction->num_waiting > 0 && --transaction->num_waiting == 0) { | 344 | if (transaction->num_waiting > 0 && --transaction->num_waiting == 0) { |
362 | if (!txn_debug) { | 345 | wlr_log(WLR_DEBUG, "Transaction %p is ready", transaction); |
363 | wlr_log(WLR_DEBUG, "Transaction %p is ready", transaction); | 346 | wl_event_source_timer_update(transaction->timer, 0); |
364 | wl_event_source_timer_update(transaction->timer, 0); | ||
365 | } | ||
366 | } | 347 | } |
367 | 348 | ||
368 | instruction->container->instruction = NULL; | 349 | instruction->container->instruction = NULL; |
369 | if (!txn_debug) { | 350 | transaction_progress_queue(); |
370 | transaction_progress_queue(); | ||
371 | } | ||
372 | } | 351 | } |
373 | 352 | ||
374 | void transaction_notify_view_ready_by_serial(struct sway_view *view, | 353 | void transaction_notify_view_ready_by_serial(struct sway_view *view, |
diff --git a/sway/main.c b/sway/main.c index 54f48340..3ba4ba75 100644 --- a/sway/main.c +++ b/sway/main.c | |||
@@ -235,14 +235,20 @@ static void drop_permissions(bool keep_caps) { | |||
235 | } | 235 | } |
236 | 236 | ||
237 | void enable_debug_flag(const char *flag) { | 237 | void enable_debug_flag(const char *flag) { |
238 | if (strcmp(flag, "render-tree") == 0) { | 238 | if (strcmp(flag, "damage=highlight") == 0) { |
239 | enable_debug_tree = true; | 239 | debug.damage = DAMAGE_HIGHLIGHT; |
240 | } else if (strncmp(flag, "damage=", 7) == 0) { | 240 | } else if (strcmp(flag, "damage=rerender") == 0) { |
241 | damage_debug = &flag[7]; | 241 | debug.damage = DAMAGE_RERENDER; |
242 | } else if (strcmp(flag, "txn-debug") == 0) { | 242 | } else if (strcmp(flag, "noatomic") == 0) { |
243 | txn_debug = true; | 243 | debug.noatomic = true; |
244 | } else if (strcmp(flag, "render-tree") == 0) { | ||
245 | debug.render_tree = true; | ||
246 | } else if (strcmp(flag, "txn-wait") == 0) { | ||
247 | debug.txn_wait = true; | ||
248 | } else if (strcmp(flag, "txn-timings") == 0) { | ||
249 | debug.txn_timings = true; | ||
244 | } else if (strncmp(flag, "txn-timeout=", 12) == 0) { | 250 | } else if (strncmp(flag, "txn-timeout=", 12) == 0) { |
245 | txn_timeout_ms = atoi(&flag[12]); | 251 | server.txn_timeout_ms = atoi(&flag[12]); |
246 | } | 252 | } |
247 | } | 253 | } |
248 | 254 | ||
diff --git a/sway/server.c b/sway/server.c index e8dc63be..00acaa01 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -128,10 +128,11 @@ bool server_init(struct sway_server *server) { | |||
128 | return false; | 128 | return false; |
129 | } | 129 | } |
130 | 130 | ||
131 | const char *debug = getenv("SWAY_DEBUG"); | 131 | // This may have been set already via -Dtxn-timeout |
132 | if (debug != NULL && strcmp(debug, "txn_timings") == 0) { | 132 | if (!server->txn_timeout_ms) { |
133 | server->debug_txn_timings = true; | 133 | server->txn_timeout_ms = 200; |
134 | } | 134 | } |
135 | |||
135 | server->dirty_containers = create_list(); | 136 | server->dirty_containers = create_list(); |
136 | server->transactions = create_list(); | 137 | server->transactions = create_list(); |
137 | 138 | ||