The open source OpenXR runtime

aux/util: use int64_t for timestamps in u_pacing

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2298>

authored by

Simon Zeni and committed by
Rylie Pavlik
f88705a3 8cf2e4bd

+281 -364
+64 -64
src/xrt/auxiliary/util/u_pacing.h
··· 83 83 * @see @ref frame-pacing. 84 84 */ 85 85 void (*predict)(struct u_pacing_compositor *upc, 86 - uint64_t now_ns, 86 + int64_t now_ns, 87 87 int64_t *out_frame_id, 88 - uint64_t *out_wake_up_time_ns, 89 - uint64_t *out_desired_present_time_ns, 90 - uint64_t *out_present_slop_ns, 91 - uint64_t *out_predicted_display_time_ns, 92 - uint64_t *out_predicted_display_period_ns, 93 - uint64_t *out_min_display_period_ns); 88 + int64_t *out_wake_up_time_ns, 89 + int64_t *out_desired_present_time_ns, 90 + int64_t *out_present_slop_ns, 91 + int64_t *out_predicted_display_time_ns, 92 + int64_t *out_predicted_display_period_ns, 93 + int64_t *out_min_display_period_ns); 94 94 95 95 /*! 96 96 * Mark a point on the frame's lifetime. ··· 108 108 void (*mark_point)(struct u_pacing_compositor *upc, 109 109 enum u_timing_point point, 110 110 int64_t frame_id, 111 - uint64_t when_ns); 111 + int64_t when_ns); 112 112 113 113 /*! 114 114 * Provide frame timing information about a delivered frame. ··· 136 136 */ 137 137 void (*info)(struct u_pacing_compositor *upc, 138 138 int64_t frame_id, 139 - uint64_t desired_present_time_ns, 140 - uint64_t actual_present_time_ns, 141 - uint64_t earliest_present_time_ns, 142 - uint64_t present_margin_ns, 143 - uint64_t when_ns); 139 + int64_t desired_present_time_ns, 140 + int64_t actual_present_time_ns, 141 + int64_t earliest_present_time_ns, 142 + int64_t present_margin_ns, 143 + int64_t when_ns); 144 144 145 145 /*! 146 146 * Provide frame timing information about GPU start and stop time. ··· 159 159 */ 160 160 void (*info_gpu)(struct u_pacing_compositor *upc, 161 161 int64_t frame_id, 162 - uint64_t gpu_start_ns, 163 - uint64_t gpu_end_ns, 164 - uint64_t when_ns); 162 + int64_t gpu_start_ns, 163 + int64_t gpu_end_ns, 164 + int64_t when_ns); 165 165 166 166 /*! 167 167 * Provide a vblank timing information, derived from the ··· 174 174 * 175 175 * @see @ref frame-pacing. 176 176 */ 177 - void (*update_vblank_from_display_control)(struct u_pacing_compositor *upc, uint64_t last_vblank_ns); 177 + void (*update_vblank_from_display_control)(struct u_pacing_compositor *upc, int64_t last_vblank_ns); 178 178 179 179 /*! 180 180 * Provide an updated estimate of the present offset. ··· 189 189 */ 190 190 void (*update_present_offset)(struct u_pacing_compositor *upc, 191 191 int64_t frame_id, 192 - uint64_t present_to_display_offset_ns); 192 + int64_t present_to_display_offset_ns); 193 193 194 194 /*! 195 195 * Destroy this u_pacing_compositor. ··· 207 207 */ 208 208 static inline void 209 209 u_pc_predict(struct u_pacing_compositor *upc, 210 - uint64_t now_ns, 210 + int64_t now_ns, 211 211 int64_t *out_frame_id, 212 - uint64_t *out_wake_up_time_ns, 213 - uint64_t *out_desired_present_time_ns, 214 - uint64_t *out_present_slop_ns, 215 - uint64_t *out_predicted_display_time_ns, 216 - uint64_t *out_predicted_display_period_ns, 217 - uint64_t *out_min_display_period_ns) 212 + int64_t *out_wake_up_time_ns, 213 + int64_t *out_desired_present_time_ns, 214 + int64_t *out_present_slop_ns, 215 + int64_t *out_predicted_display_time_ns, 216 + int64_t *out_predicted_display_period_ns, 217 + int64_t *out_min_display_period_ns) 218 218 { 219 219 upc->predict(upc, // 220 220 now_ns, // ··· 236 236 * @ingroup aux_pacing 237 237 */ 238 238 static inline void 239 - u_pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, uint64_t when_ns) 239 + u_pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, int64_t when_ns) 240 240 { 241 241 upc->mark_point(upc, point, frame_id, when_ns); 242 242 } ··· 252 252 static inline void 253 253 u_pc_info(struct u_pacing_compositor *upc, 254 254 int64_t frame_id, 255 - uint64_t desired_present_time_ns, 256 - uint64_t actual_present_time_ns, 257 - uint64_t earliest_present_time_ns, 258 - uint64_t present_margin_ns, 259 - uint64_t when_ns) 255 + int64_t desired_present_time_ns, 256 + int64_t actual_present_time_ns, 257 + int64_t earliest_present_time_ns, 258 + int64_t present_margin_ns, 259 + int64_t when_ns) 260 260 { 261 261 upc->info(upc, frame_id, desired_present_time_ns, actual_present_time_ns, earliest_present_time_ns, 262 262 present_margin_ns, when_ns); ··· 273 273 */ 274 274 static inline void 275 275 u_pc_info_gpu( 276 - struct u_pacing_compositor *upc, int64_t frame_id, uint64_t gpu_start_ns, uint64_t gpu_end_ns, uint64_t when_ns) 276 + struct u_pacing_compositor *upc, int64_t frame_id, int64_t gpu_start_ns, int64_t gpu_end_ns, int64_t when_ns) 277 277 { 278 278 upc->info_gpu(upc, frame_id, gpu_start_ns, gpu_end_ns, when_ns); 279 279 } ··· 287 287 * @ingroup aux_pacing 288 288 */ 289 289 static inline void 290 - u_pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t last_vblank_ns) 290 + u_pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, int64_t last_vblank_ns) 291 291 { 292 292 upc->update_vblank_from_display_control(upc, last_vblank_ns); 293 293 } ··· 301 301 * @ingroup aux_pacing 302 302 */ 303 303 static inline void 304 - u_pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, uint64_t present_to_display_offset_ns) 304 + u_pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, int64_t present_to_display_offset_ns) 305 305 { 306 306 upc->update_present_offset(upc, frame_id, present_to_display_offset_ns); 307 307 } ··· 362 362 * @param[out] out_predicted_display_period Predicted display period. 363 363 */ 364 364 void (*predict)(struct u_pacing_app *upa, 365 - uint64_t now_ns, 365 + int64_t now_ns, 366 366 int64_t *out_frame_id, 367 - uint64_t *out_wake_up_time, 368 - uint64_t *out_predicted_display_time, 369 - uint64_t *out_predicted_display_period); 367 + int64_t *out_wake_up_time, 368 + int64_t *out_predicted_display_time, 369 + int64_t *out_predicted_display_period); 370 370 371 371 /*! 372 372 * Mark a point on the frame's lifetime. ··· 378 378 * 379 379 * @see @ref frame-pacing. 380 380 */ 381 - void (*mark_point)(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, uint64_t when_ns); 381 + void (*mark_point)(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, int64_t when_ns); 382 382 383 383 /*! 384 384 * When a frame has been discarded. ··· 387 387 * @param[in] frame_id The frame ID to mark as discarded. 388 388 * @param[in] when_ns The time when it was discarded, nominally from @ref os_monotonic_get_ns 389 389 */ 390 - void (*mark_discarded)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns); 390 + void (*mark_discarded)(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns); 391 391 392 392 /*! 393 393 * A frame has been delivered from the client, see `xrEndFrame`. The GPU might ··· 398 398 * @param[in] when_ns The time when it was delivered, nominally from @ref os_monotonic_get_ns 399 399 * @param[in] display_time_ns The time the frame is to be displayed. 400 400 */ 401 - void (*mark_delivered)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, uint64_t display_time_ns); 401 + void (*mark_delivered)(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t display_time_ns); 402 402 403 403 /*! 404 404 * A frame has been completed rendered by the GPU, this can happen after `xrEndFrame` has returned. ··· 407 407 * @param[in] frame_id The frame ID to mark as delivered. 408 408 * @param[in] when_ns The time when it the gpu was finished, nominally from @ref os_monotonic_get_ns 409 409 */ 410 - void (*mark_gpu_done)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns); 410 + void (*mark_gpu_done)(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns); 411 411 412 412 /*! 413 413 * Latch a frame for rendering for delivery to the native compositor, ··· 420 420 * @param[in] system_frame_id The ID of the system frame that is 421 421 * latching the app's frame. 422 422 */ 423 - void (*latched)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, int64_t system_frame_id); 423 + void (*latched)(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t system_frame_id); 424 424 425 425 /*! 426 426 * Mark a frame as completely retired, will never be latched (used by ··· 431 431 * @param[in] frame_id The frame ID of the latched frame. 432 432 * @param[in] when_ns Time when the latching happened. 433 433 */ 434 - void (*retired)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns); 434 + void (*retired)(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns); 435 435 436 436 /*! 437 437 * Add a new sample point from the main render loop. ··· 452 452 * was woken up by the main compositor. 453 453 */ 454 454 void (*info)(struct u_pacing_app *upa, 455 - uint64_t predicted_display_time_ns, 456 - uint64_t predicted_display_period_ns, 457 - uint64_t extra_ns); 455 + int64_t predicted_display_time_ns, 456 + int64_t predicted_display_period_ns, 457 + int64_t extra_ns); 458 458 459 459 /*! 460 460 * Destroy this u_pacing_app. ··· 472 472 */ 473 473 static inline void 474 474 u_pa_predict(struct u_pacing_app *upa, 475 - uint64_t now_ns, 475 + int64_t now_ns, 476 476 int64_t *out_frame_id, 477 - uint64_t *out_wake_up_time, 478 - uint64_t *out_predicted_display_time, 479 - uint64_t *out_predicted_display_period) 477 + int64_t *out_wake_up_time, 478 + int64_t *out_predicted_display_time, 479 + int64_t *out_predicted_display_period) 480 480 { 481 481 upa->predict(upa, now_ns, out_frame_id, out_wake_up_time, out_predicted_display_time, 482 482 out_predicted_display_period); ··· 491 491 * @ingroup aux_pacing 492 492 */ 493 493 static inline void 494 - u_pa_mark_point(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, uint64_t when_ns) 494 + u_pa_mark_point(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, int64_t when_ns) 495 495 { 496 496 upa->mark_point(upa, frame_id, point, when_ns); 497 497 } ··· 505 505 * @ingroup aux_pacing 506 506 */ 507 507 static inline void 508 - u_pa_mark_discarded(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns) 508 + u_pa_mark_discarded(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns) 509 509 { 510 510 upa->mark_discarded(upa, frame_id, when_ns); 511 511 } ··· 519 519 * @ingroup aux_pacing 520 520 */ 521 521 static inline void 522 - u_pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, uint64_t display_time_ns) 522 + u_pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t display_time_ns) 523 523 { 524 524 upa->mark_delivered(upa, frame_id, when_ns, display_time_ns); 525 525 } ··· 533 533 * @ingroup aux_pacing 534 534 */ 535 535 static inline void 536 - u_pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns) 536 + u_pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns) 537 537 { 538 538 upa->mark_gpu_done(upa, frame_id, when_ns); 539 539 } ··· 548 548 */ 549 549 static inline void 550 550 u_pa_info(struct u_pacing_app *upa, 551 - uint64_t predicted_display_time_ns, 552 - uint64_t predicted_display_period_ns, 553 - uint64_t extra_ns) 551 + int64_t predicted_display_time_ns, 552 + int64_t predicted_display_period_ns, 553 + int64_t extra_ns) 554 554 { 555 555 upa->info(upa, predicted_display_time_ns, predicted_display_period_ns, extra_ns); 556 556 } ··· 564 564 * @ingroup aux_pacing 565 565 */ 566 566 static inline void 567 - u_pa_latched(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, int64_t system_frame_id) 567 + u_pa_latched(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t system_frame_id) 568 568 { 569 569 upa->latched(upa, frame_id, when_ns, system_frame_id); 570 570 } ··· 578 578 * @ingroup aux_pacing 579 579 */ 580 580 static inline void 581 - u_pa_retired(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns) 581 + u_pa_retired(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns) 582 582 { 583 583 upa->retired(upa, frame_id, when_ns); 584 584 } ··· 680 680 struct u_pc_display_timing_config 681 681 { 682 682 //! How long after "present" is the image actually displayed 683 - uint64_t present_to_display_offset_ns; 683 + int64_t present_to_display_offset_ns; 684 684 //! Extra margin that is added to compositor time, between end of draw and present 685 - uint64_t margin_ns; 685 + int64_t margin_ns; 686 686 /*! 687 687 * @name Frame-Relative Values 688 688 * All these values are in "percentage points of the nominal frame period" so they can work across ··· 725 725 * @see u_pacing_compositor 726 726 */ 727 727 xrt_result_t 728 - u_pc_display_timing_create(uint64_t estimated_frame_period_ns, 728 + u_pc_display_timing_create(int64_t estimated_frame_period_ns, 729 729 const struct u_pc_display_timing_config *config, 730 730 struct u_pacing_compositor **out_upc); 731 731 ··· 742 742 * @see u_pacing_compositor 743 743 */ 744 744 xrt_result_t 745 - u_pc_fake_create(uint64_t estimated_frame_period_ns, uint64_t now_ns, struct u_pacing_compositor **out_upc); 745 + u_pc_fake_create(int64_t estimated_frame_period_ns, int64_t now_ns, struct u_pacing_compositor **out_upc); 746 746 747 747 /*! 748 748 * Creates a new application pacing factory helper.
+69 -69
src/xrt/auxiliary/util/u_pacing_app.c
··· 68 68 int64_t frame_id; 69 69 70 70 //! How long we thought the frame would take. 71 - uint64_t predicted_frame_time_ns; 71 + int64_t predicted_frame_time_ns; 72 72 73 73 //! When we predicted the app should wake up. 74 - uint64_t predicted_wake_up_time_ns; 74 + int64_t predicted_wake_up_time_ns; 75 75 76 76 //! When the client's GPU work should have completed. 77 - uint64_t predicted_gpu_done_time_ns; 77 + int64_t predicted_gpu_done_time_ns; 78 78 79 79 //! When we predicted this frame to be shown. 80 - uint64_t predicted_display_time_ns; 80 + int64_t predicted_display_time_ns; 81 81 82 82 //! The selected display period. 83 - uint64_t predicted_display_period_ns; 83 + int64_t predicted_display_period_ns; 84 84 85 85 /*! 86 86 * When the app told us to display this frame, can be different 87 87 * then the predicted display time so we track that separately. 88 88 */ 89 - uint64_t display_time_ns; 89 + int64_t display_time_ns; 90 90 91 91 //! When something happened. 92 92 struct 93 93 { 94 - uint64_t predicted_ns; 95 - uint64_t wait_woke_ns; 96 - uint64_t begin_ns; 97 - uint64_t delivered_ns; 98 - uint64_t gpu_done_ns; 94 + int64_t predicted_ns; 95 + int64_t wait_woke_ns; 96 + int64_t begin_ns; 97 + int64_t delivered_ns; 98 + int64_t gpu_done_ns; 99 99 } when; 100 100 101 101 enum u_pa_state state; ··· 140 140 struct 141 141 { 142 142 //! App time between wait returning and begin being called. 143 - uint64_t cpu_time_ns; 143 + int64_t cpu_time_ns; 144 144 //! Time between begin and frame data being delivered. 145 - uint64_t draw_time_ns; 145 + int64_t draw_time_ns; 146 146 //! Time between the frame data being delivered and GPU completing. 147 - uint64_t gpu_time_ns; 147 + int64_t gpu_time_ns; 148 148 } app; //!< App statistics. 149 149 150 150 struct 151 151 { 152 152 //! The last display time that the thing driving this helper got. 153 - uint64_t predicted_display_time_ns; 153 + int64_t predicted_display_time_ns; 154 154 //! The last display period the hardware is running at. 155 - uint64_t predicted_display_period_ns; 155 + int64_t predicted_display_period_ns; 156 156 //! The extra time needed by the thing driving this helper. 157 - uint64_t extra_ns; 157 + int64_t extra_ns; 158 158 } last_input; 159 159 160 - uint64_t last_returned_ns; 160 + int64_t last_returned_ns; 161 161 }; 162 162 163 163 ··· 204 204 #define DEBUG_PRINT_ID_FRAME_POINT(ID, F, P) \ 205 205 UPA_LOG_T("%" PRIi64 " (%" PRIi64 ", %s) %s", frame_id, F->frame_id, state_to_str(F->state), point_to_str(P)); 206 206 207 - #define GET_INDEX_FROM_ID(RT, ID) ((uint64_t)(ID) % FRAME_COUNT) 207 + #define GET_INDEX_FROM_ID(RT, ID) ((int64_t)(ID) % FRAME_COUNT) 208 208 209 209 #define IIR_ALPHA_LT 0.8 210 210 #define IIR_ALPHA_GT 0.8 211 211 212 212 static void 213 - do_iir_filter(uint64_t *target, double alpha_lt, double alpha_gt, uint64_t sample) 213 + do_iir_filter(int64_t *target, double alpha_lt, double alpha_gt, int64_t sample) 214 214 { 215 - uint64_t t = *target; 215 + int64_t t = *target; 216 216 double alpha = t < sample ? alpha_lt : alpha_gt; 217 217 double a = time_ns_to_s(t) * alpha; 218 218 double b = time_ns_to_s(sample) * (1.0 - alpha); 219 219 *target = time_s_to_ns(a + b); 220 220 } 221 221 222 - static uint64_t 222 + static int64_t 223 223 min_period(const struct pacing_app *pa) 224 224 { 225 225 return pa->last_input.predicted_display_period_ns; 226 226 } 227 227 228 - static uint64_t 228 + static int64_t 229 229 min_app_time(const struct pacing_app *pa) 230 230 { 231 - return (uint64_t)(pa->min_app_time_ms.val * (double)U_TIME_1MS_IN_NS); 231 + return (int64_t)(pa->min_app_time_ms.val * (double)U_TIME_1MS_IN_NS); 232 232 } 233 233 234 - static uint64_t 234 + static int64_t 235 235 margin_time(const struct pacing_app *pa) 236 236 { 237 - return (uint64_t)(pa->min_margin_ms.val * (double)U_TIME_1MS_IN_NS); 237 + return (int64_t)(pa->min_margin_ms.val * (double)U_TIME_1MS_IN_NS); 238 238 } 239 239 240 - static uint64_t 240 + static int64_t 241 241 last_sample_displayed(const struct pacing_app *pa) 242 242 { 243 243 return pa->last_input.predicted_display_time_ns; 244 244 } 245 245 246 - static uint64_t 246 + static int64_t 247 247 last_return_predicted_display(const struct pacing_app *pa) 248 248 { 249 249 return pa->last_returned_ns; 250 250 } 251 251 252 - static uint64_t 252 + static int64_t 253 253 total_app_time_ns(const struct pacing_app *pa) 254 254 { 255 - uint64_t total_ns = pa->app.cpu_time_ns + pa->app.draw_time_ns + pa->app.gpu_time_ns; 256 - uint64_t min_ns = min_app_time(pa); 255 + int64_t total_ns = pa->app.cpu_time_ns + pa->app.draw_time_ns + pa->app.gpu_time_ns; 256 + int64_t min_ns = min_app_time(pa); 257 257 258 258 if (total_ns < min_ns) { 259 259 total_ns = min_ns; ··· 262 262 return total_ns; 263 263 } 264 264 265 - static uint64_t 265 + static int64_t 266 266 total_compositor_time_ns(const struct pacing_app *pa) 267 267 { 268 268 return margin_time(pa) + pa->last_input.extra_ns; 269 269 } 270 270 271 - static uint64_t 271 + static int64_t 272 272 total_app_and_compositor_time_ns(const struct pacing_app *pa) 273 273 { 274 274 return total_app_time_ns(pa) + total_compositor_time_ns(pa); 275 275 } 276 276 277 - static uint64_t 277 + static int64_t 278 278 calc_period(const struct pacing_app *pa) 279 279 { 280 280 // Error checking. 281 - uint64_t base_period_ns = min_period(pa); 281 + int64_t base_period_ns = min_period(pa); 282 282 if (base_period_ns == 0) { 283 283 assert(false && "Have not yet received and samples from timing driver."); 284 284 base_period_ns = U_TIME_1MS_IN_NS * 16; // Sure 285 285 } 286 286 287 287 // Calculate the using both values separately. 288 - uint64_t period_ns = base_period_ns; 288 + int64_t period_ns = base_period_ns; 289 289 while (pa->app.cpu_time_ns > period_ns) { 290 290 period_ns += base_period_ns; 291 291 } ··· 301 301 return period_ns; 302 302 } 303 303 304 - static uint64_t 305 - predict_display_time(const struct pacing_app *pa, uint64_t now_ns, uint64_t period_ns) 304 + static int64_t 305 + predict_display_time(const struct pacing_app *pa, int64_t now_ns, int64_t period_ns) 306 306 { 307 307 308 308 // Total app and compositor time to produce a frame 309 - uint64_t app_and_compositor_time_ns = total_app_and_compositor_time_ns(pa); 309 + int64_t app_and_compositor_time_ns = total_app_and_compositor_time_ns(pa); 310 310 311 311 // Start from the last time that the driver displayed something. 312 - uint64_t val = last_sample_displayed(pa); 312 + int64_t val = last_sample_displayed(pa); 313 313 314 314 // Return a time after the last returned display time. Add half the 315 315 // display period to the comparison for robustness when the last display ··· 368 368 } 369 369 370 370 #ifdef U_TRACE_TRACY // Uses Tracy specific things. 371 - uint64_t cpu_ns = f->when.begin_ns - f->when.wait_woke_ns; 371 + int64_t cpu_ns = f->when.begin_ns - f->when.wait_woke_ns; 372 372 TracyCPlot("App CPU(ms)", time_ns_to_ms_f(cpu_ns)); 373 373 374 - uint64_t draw_ns = f->when.delivered_ns - f->when.begin_ns; 374 + int64_t draw_ns = f->when.delivered_ns - f->when.begin_ns; 375 375 TracyCPlot("App Draw(ms)", time_ns_to_ms_f(draw_ns)); 376 376 377 - uint64_t gpu_ns = f->when.gpu_done_ns - f->when.delivered_ns; 377 + int64_t gpu_ns = f->when.gpu_done_ns - f->when.delivered_ns; 378 378 TracyCPlot("App GPU(ms)", time_ns_to_ms_f(gpu_ns)); 379 379 380 - uint64_t frame_ns = f->when.gpu_done_ns - f->when.wait_woke_ns; 380 + int64_t frame_ns = f->when.gpu_done_ns - f->when.wait_woke_ns; 381 381 TracyCPlot("App Frame(ms)", time_ns_to_ms_f(frame_ns)); 382 382 383 383 int64_t wake_diff_ns = (int64_t)f->when.wait_woke_ns - (int64_t)f->predicted_wake_up_time_ns; ··· 394 394 TE_BEG(pa_cpu, f->when.predicted_ns, "sleep"); 395 395 TE_END(pa_cpu, f->when.wait_woke_ns); 396 396 397 - uint64_t cpu_start_ns = f->when.wait_woke_ns + 1; 397 + int64_t cpu_start_ns = f->when.wait_woke_ns + 1; 398 398 TE_BEG(pa_cpu, cpu_start_ns, "cpu"); 399 399 TE_END(pa_cpu, f->when.begin_ns); 400 400 ··· 432 432 433 433 static void 434 434 pa_predict(struct u_pacing_app *upa, 435 - uint64_t now_ns, 435 + int64_t now_ns, 436 436 int64_t *out_frame_id, 437 - uint64_t *out_wake_up_time, 438 - uint64_t *out_predicted_display_time, 439 - uint64_t *out_predicted_display_period) 437 + int64_t *out_wake_up_time, 438 + int64_t *out_predicted_display_time, 439 + int64_t *out_predicted_display_period) 440 440 { 441 441 struct pacing_app *pa = pacing_app(upa); 442 442 ··· 445 445 446 446 DEBUG_PRINT_ID(frame_id); 447 447 448 - uint64_t period_ns; 448 + int64_t period_ns; 449 449 450 450 /* 451 451 * We can either limit the application to a calculated frame rate that ··· 458 458 period_ns = calc_period(pa); 459 459 } 460 460 461 - uint64_t predict_ns = predict_display_time(pa, now_ns, period_ns); 461 + int64_t predict_ns = predict_display_time(pa, now_ns, period_ns); 462 462 // How long we think the frame should take. 463 - uint64_t frame_time_ns = total_app_time_ns(pa); 463 + int64_t frame_time_ns = total_app_time_ns(pa); 464 464 // When should the client wake up. 465 - uint64_t wake_up_time_ns = predict_ns - total_app_and_compositor_time_ns(pa); 465 + int64_t wake_up_time_ns = predict_ns - total_app_and_compositor_time_ns(pa); 466 466 // When the client's GPU work should have completed. 467 - uint64_t gpu_done_time_ns = predict_ns - total_compositor_time_ns(pa); 467 + int64_t gpu_done_time_ns = predict_ns - total_compositor_time_ns(pa); 468 468 469 469 pa->last_returned_ns = predict_ns; 470 470 ··· 492 492 } 493 493 494 494 static void 495 - pa_mark_point(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, uint64_t when_ns) 495 + pa_mark_point(struct u_pacing_app *upa, int64_t frame_id, enum u_timing_point point, int64_t when_ns) 496 496 { 497 497 struct pacing_app *pa = pacing_app(upa); 498 498 ··· 523 523 } 524 524 525 525 static void 526 - pa_mark_discarded(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns) 526 + pa_mark_discarded(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns) 527 527 { 528 528 struct pacing_app *pa = pacing_app(upa); 529 529 ··· 548 548 } 549 549 550 550 static void 551 - pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, uint64_t display_time_ns) 551 + pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t display_time_ns) 552 552 { 553 553 struct pacing_app *pa = pacing_app(upa); 554 554 ··· 567 567 } 568 568 569 569 static void 570 - pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns) 570 + pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns) 571 571 { 572 572 struct pacing_app *pa = pacing_app(upa); 573 573 ··· 595 595 late = true; 596 596 } 597 597 598 - uint64_t diff_cpu_ns = f->when.begin_ns - f->when.wait_woke_ns; 599 - uint64_t diff_draw_ns = f->when.delivered_ns - f->when.begin_ns; 600 - uint64_t diff_gpu_ns = f->when.gpu_done_ns - f->when.delivered_ns; 598 + int64_t diff_cpu_ns = f->when.begin_ns - f->when.wait_woke_ns; 599 + int64_t diff_draw_ns = f->when.delivered_ns - f->when.begin_ns; 600 + int64_t diff_gpu_ns = f->when.gpu_done_ns - f->when.delivered_ns; 601 601 602 602 UPA_LOG_D( 603 603 "Delivered frame %.2fms %s." // ··· 628 628 } 629 629 630 630 static void 631 - pa_latched(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns, int64_t system_frame_id) 631 + pa_latched(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns, int64_t system_frame_id) 632 632 { 633 633 struct pacing_app *pa = pacing_app(upa); 634 634 ··· 652 652 } 653 653 654 654 static void 655 - pa_retired(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns) 655 + pa_retired(struct u_pacing_app *upa, int64_t frame_id, int64_t when_ns) 656 656 { 657 657 struct pacing_app *pa = pacing_app(upa); 658 658 ··· 673 673 674 674 static void 675 675 pa_info(struct u_pacing_app *upa, 676 - uint64_t predicted_display_time_ns, 677 - uint64_t predicted_display_period_ns, 678 - uint64_t extra_ns) 676 + int64_t predicted_display_time_ns, 677 + int64_t predicted_display_period_ns, 678 + int64_t extra_ns) 679 679 { 680 680 struct pacing_app *pa = pacing_app(upa); 681 681 ··· 732 732 u_var_add_root(pa, "App timing info", true); 733 733 u_var_add_draggable_f32(pa, &pa->min_margin_ms, "Minimum margin(ms)"); 734 734 u_var_add_draggable_f32(pa, &pa->min_app_time_ms, "Minimum app time(ms)"); 735 - u_var_add_ro_u64(pa, &pa->app.cpu_time_ns, "CPU time(ns)"); 736 - u_var_add_ro_u64(pa, &pa->app.draw_time_ns, "Draw time(ns)"); 737 - u_var_add_ro_u64(pa, &pa->app.gpu_time_ns, "GPU time(ns)"); 735 + u_var_add_ro_i64(pa, &pa->app.cpu_time_ns, "CPU time(ns)"); 736 + u_var_add_ro_i64(pa, &pa->app.draw_time_ns, "Draw time(ns)"); 737 + u_var_add_ro_i64(pa, &pa->app.gpu_time_ns, "GPU time(ns)"); 738 738 739 739 *out_upa = &pa->base; 740 740
+64 -64
src/xrt/auxiliary/util/u_pacing_compositor.c
··· 56 56 int64_t frame_id; 57 57 58 58 //! When this frame was last used for a prediction. Set in `predict_next_frame`. 59 - uint64_t when_predict_ns; 59 + int64_t when_predict_ns; 60 60 61 61 //! When should the compositor wake up. Set in `predict_next_frame`. 62 - uint64_t wake_up_time_ns; 62 + int64_t wake_up_time_ns; 63 63 64 64 //! When we last woke up the compositor after its equivalent of wait_frame. Set in `pc_mark_point` with 65 65 //! `U_TIMING_POINT_WAKE_UP`. 66 - uint64_t when_woke_ns; 66 + int64_t when_woke_ns; 67 67 68 68 //! When the compositor started rendering a frame 69 - uint64_t when_began_ns; 69 + int64_t when_began_ns; 70 70 71 71 //! When the compositor finished rendering a frame 72 - uint64_t when_submitted_ns; 72 + int64_t when_submitted_ns; 73 73 74 74 //! When new frame timing info was last added. 75 - uint64_t when_infoed_ns; 75 + int64_t when_infoed_ns; 76 76 77 77 //! How much time we currently expect the compositor to take rendering a frame. Updated in `predict_next_frame` 78 - uint64_t current_comp_time_ns; 78 + int64_t current_comp_time_ns; 79 79 80 - uint64_t expected_done_time_ns; //!< When we expect the compositor to be done with its frame. 81 - uint64_t desired_present_time_ns; //!< The GPU should start scanning out at this time. 82 - uint64_t predicted_display_time_ns; //!< At what time have we predicted that pixels turns to photons. 83 - uint64_t present_margin_ns; 84 - uint64_t actual_present_time_ns; 85 - uint64_t earliest_present_time_ns; 80 + int64_t expected_done_time_ns; //!< When we expect the compositor to be done with its frame. 81 + int64_t desired_present_time_ns; //!< The GPU should start scanning out at this time. 82 + int64_t predicted_display_time_ns; //!< At what time have we predicted that pixels turns to photons. 83 + int64_t present_margin_ns; 84 + int64_t actual_present_time_ns; 85 + int64_t earliest_present_time_ns; 86 86 87 87 enum frame_state state; 88 88 }; ··· 96 96 * the display engine starts scanning out from the buffers we provided, 97 97 * and not when the pixels turned into photons that the user sees. 98 98 */ 99 - uint64_t present_to_display_offset_ns; 99 + int64_t present_to_display_offset_ns; 100 100 101 101 /*! 102 102 * Frame period of the device. 103 103 */ 104 - uint64_t frame_period_ns; 104 + int64_t frame_period_ns; 105 105 106 106 /*! 107 107 * The amount of time that the compositor needs to render frame. 108 108 */ 109 - uint64_t comp_time_ns; 109 + int64_t comp_time_ns; 110 110 111 111 /*! 112 112 * Used to generate frame IDs. ··· 116 116 /*! 117 117 * The maximum amount we give to the compositor. 118 118 */ 119 - uint64_t comp_time_max_ns; 119 + int64_t comp_time_max_ns; 120 120 121 121 /*! 122 122 * If we missed a frame, back off this much. 123 123 */ 124 - uint64_t adjust_missed_ns; 124 + int64_t adjust_missed_ns; 125 125 126 126 /*! 127 127 * Adjustment of time if we didn't miss the frame, 128 128 * also used as range to stay around timing target. 129 129 */ 130 - uint64_t adjust_non_miss_ns; 130 + int64_t adjust_non_miss_ns; 131 131 132 132 /*! 133 133 * Extra time between end of draw time and when the present happens. 134 134 */ 135 - uint64_t margin_ns; 135 + int64_t margin_ns; 136 136 137 137 /*! 138 138 * Frame store. ··· 159 159 return (double)(t / 1000) / 1000.0; 160 160 } 161 161 162 - static uint64_t 163 - get_percent_of_time(uint64_t time_ns, uint32_t fraction_percent) 162 + static int64_t 163 + get_percent_of_time(int64_t time_ns, uint32_t fraction_percent) 164 164 { 165 165 double fraction = (double)fraction_percent / 100.0; 166 166 return time_s_to_ns(time_ns_to_s(time_ns) * fraction); 167 167 } 168 168 169 - static uint64_t 169 + static int64_t 170 170 calc_total_comp_time(struct pacing_compositor *pc) 171 171 { 172 172 return pc->comp_time_ns + pc->margin_ns; 173 173 } 174 174 175 - static uint64_t 176 - calc_display_time_from_present_time(struct pacing_compositor *pc, uint64_t desired_present_time_ns) 175 + static int64_t 176 + calc_display_time_from_present_time(struct pacing_compositor *pc, int64_t desired_present_time_ns) 177 177 { 178 178 return desired_present_time_ns + pc->present_to_display_offset_ns; 179 179 } 180 180 181 181 static inline bool 182 - is_within_of_each_other(uint64_t l, uint64_t r, uint64_t range) 182 + is_within_of_each_other(int64_t l, int64_t r, int64_t range) 183 183 { 184 184 int64_t t = (int64_t)l - (int64_t)r; 185 185 return (-(int64_t)range < t) && (t < (int64_t)range); 186 186 } 187 187 188 188 static inline bool 189 - is_within_half_ms(uint64_t l, uint64_t r) 189 + is_within_half_ms(int64_t l, int64_t r) 190 190 { 191 191 return is_within_of_each_other(l, r, U_TIME_HALF_MS_IN_NS); 192 192 } ··· 238 238 static struct frame * 239 239 get_latest_frame_with_state_at_least(struct pacing_compositor *pc, enum frame_state state) 240 240 { 241 - uint64_t start_from = pc->next_frame_id; 242 - uint64_t count = 1; 241 + int64_t start_from = pc->next_frame_id; 242 + int64_t count = 1; 243 243 244 244 while (start_from >= count && count < NUM_FRAMES) { 245 245 int64_t frame_id = start_from - count; ··· 258 258 * initialize frame::desired_present_time_ns (with a crude estimate) and frame::when_predict_ns. 259 259 */ 260 260 static struct frame * 261 - do_clean_slate_frame(struct pacing_compositor *pc, uint64_t now_ns) 261 + do_clean_slate_frame(struct pacing_compositor *pc, int64_t now_ns) 262 262 { 263 263 struct frame *f = create_frame(pc, STATE_PREDICTED); 264 264 265 265 // Wild shot in the dark. 266 - uint64_t the_time_ns = now_ns + pc->frame_period_ns * 10; 266 + int64_t the_time_ns = now_ns + pc->frame_period_ns * 10; 267 267 f->when_predict_ns = now_ns; 268 268 f->desired_present_time_ns = the_time_ns; 269 269 ··· 275 275 * prediction in it. 276 276 */ 277 277 static struct frame * 278 - walk_forward_through_frames(struct pacing_compositor *pc, uint64_t last_present_time_ns, uint64_t now_ns) 278 + walk_forward_through_frames(struct pacing_compositor *pc, int64_t last_present_time_ns, int64_t now_ns) 279 279 { 280 280 // This is the earliest possible time we could present, assuming rendering still must take place. 281 - uint64_t from_time_ns = now_ns + calc_total_comp_time(pc); 282 - uint64_t desired_present_time_ns = last_present_time_ns + pc->frame_period_ns; 281 + int64_t from_time_ns = now_ns + calc_total_comp_time(pc); 282 + int64_t desired_present_time_ns = last_present_time_ns + pc->frame_period_ns; 283 283 284 284 while (desired_present_time_ns <= from_time_ns) { 285 285 UPC_LOG_D( ··· 303 303 } 304 304 305 305 static struct frame * 306 - predict_next_frame(struct pacing_compositor *pc, uint64_t now_ns) 306 + predict_next_frame(struct pacing_compositor *pc, int64_t now_ns) 307 307 { 308 308 struct frame *f = NULL; 309 309 // Last earliest display time, can be zero. ··· 320 320 321 321 int64_t diff_id = last_predicted->frame_id - last_completed->frame_id; 322 322 int64_t diff_ns = last_completed->desired_present_time_ns - last_completed->earliest_present_time_ns; 323 - uint64_t adjusted_last_present_time_ns = 323 + int64_t adjusted_last_present_time_ns = 324 324 last_completed->earliest_present_time_ns + diff_id * pc->frame_period_ns; 325 325 326 326 if (diff_ns > U_TIME_1MS_IN_NS) { ··· 356 356 static void 357 357 adjust_comp_time(struct pacing_compositor *pc, struct frame *f) 358 358 { 359 - uint64_t comp_time_ns = pc->comp_time_ns; 359 + int64_t comp_time_ns = pc->comp_time_ns; 360 360 361 361 if (f->actual_present_time_ns > f->desired_present_time_ns && 362 362 !is_within_half_ms(f->actual_present_time_ns, f->desired_present_time_ns)) { ··· 448 448 TE_BEG(pc_cpu, f->when_predict_ns, "sleep"); 449 449 TE_END(pc_cpu, f->wake_up_time_ns); 450 450 451 - uint64_t oversleep_start_ns = f->wake_up_time_ns + 1; 451 + int64_t oversleep_start_ns = f->wake_up_time_ns + 1; 452 452 if (f->when_woke_ns > oversleep_start_ns) { 453 453 TE_BEG(pc_cpu, oversleep_start_ns, "oversleep"); 454 454 TE_END(pc_cpu, f->when_woke_ns); ··· 461 461 * 462 462 */ 463 463 464 - uint64_t gpu_end_ns = f->actual_present_time_ns - f->present_margin_ns; 464 + int64_t gpu_end_ns = f->actual_present_time_ns - f->present_margin_ns; 465 465 if (gpu_end_ns > f->when_submitted_ns) { 466 466 TE_BEG(pc_gpu, f->when_submitted_ns, "gpu"); 467 467 TE_END(pc_gpu, gpu_end_ns); ··· 553 553 554 554 static void 555 555 pc_predict(struct u_pacing_compositor *upc, 556 - uint64_t now_ns, 556 + int64_t now_ns, 557 557 int64_t *out_frame_id, 558 - uint64_t *out_wake_up_time_ns, 559 - uint64_t *out_desired_present_time_ns, 560 - uint64_t *out_present_slop_ns, 561 - uint64_t *out_predicted_display_time_ns, 562 - uint64_t *out_predicted_display_period_ns, 563 - uint64_t *out_min_display_period_ns) 558 + int64_t *out_wake_up_time_ns, 559 + int64_t *out_desired_present_time_ns, 560 + int64_t *out_present_slop_ns, 561 + int64_t *out_predicted_display_time_ns, 562 + int64_t *out_predicted_display_period_ns, 563 + int64_t *out_min_display_period_ns) 564 564 { 565 565 struct pacing_compositor *pc = pacing_compositor(upc); 566 566 567 567 struct frame *f = predict_next_frame(pc, now_ns); 568 568 569 - uint64_t wake_up_time_ns = f->wake_up_time_ns; 570 - uint64_t desired_present_time_ns = f->desired_present_time_ns; 571 - uint64_t present_slop_ns = PRESENT_SLOP_NS; 572 - uint64_t predicted_display_time_ns = f->predicted_display_time_ns; 573 - uint64_t predicted_display_period_ns = pc->frame_period_ns; 574 - uint64_t min_display_period_ns = pc->frame_period_ns; 569 + int64_t wake_up_time_ns = f->wake_up_time_ns; 570 + int64_t desired_present_time_ns = f->desired_present_time_ns; 571 + int64_t present_slop_ns = PRESENT_SLOP_NS; 572 + int64_t predicted_display_time_ns = f->predicted_display_time_ns; 573 + int64_t predicted_display_period_ns = pc->frame_period_ns; 574 + int64_t min_display_period_ns = pc->frame_period_ns; 575 575 576 576 *out_frame_id = f->frame_id; 577 577 *out_wake_up_time_ns = wake_up_time_ns; ··· 583 583 } 584 584 585 585 static void 586 - pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, uint64_t when_ns) 586 + pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, int64_t when_ns) 587 587 { 588 588 struct pacing_compositor *pc = pacing_compositor(upc); 589 589 struct frame *f = get_frame(pc, frame_id); ··· 622 622 static void 623 623 pc_info(struct u_pacing_compositor *upc, 624 624 int64_t frame_id, 625 - uint64_t desired_present_time_ns, 626 - uint64_t actual_present_time_ns, 627 - uint64_t earliest_present_time_ns, 628 - uint64_t present_margin_ns, 629 - uint64_t when_ns) 625 + int64_t desired_present_time_ns, 626 + int64_t actual_present_time_ns, 627 + int64_t earliest_present_time_ns, 628 + int64_t present_margin_ns, 629 + int64_t when_ns) 630 630 { 631 631 struct pacing_compositor *pc = pacing_compositor(upc); 632 632 (void)pc; ··· 642 642 } 643 643 644 644 assert(f->state == STATE_SUBMITTED); 645 - XRT_MAYBE_UNUSED uint64_t unslopped_desired_present_time_ns = desired_present_time_ns + PRESENT_SLOP_NS; 645 + XRT_MAYBE_UNUSED int64_t unslopped_desired_present_time_ns = desired_present_time_ns + PRESENT_SLOP_NS; 646 646 assert(f->desired_present_time_ns == desired_present_time_ns || 647 647 f->desired_present_time_ns == unslopped_desired_present_time_ns); 648 648 ··· 652 652 f->present_margin_ns = present_margin_ns; 653 653 f->state = STATE_INFO; 654 654 655 - uint64_t since_last_frame_ns = 0; 655 + int64_t since_last_frame_ns = 0; 656 656 if (last != NULL) { 657 657 since_last_frame_ns = f->desired_present_time_ns - last->desired_present_time_ns; 658 658 } ··· 695 695 696 696 static void 697 697 pc_info_gpu( 698 - struct u_pacing_compositor *upc, int64_t frame_id, uint64_t gpu_start_ns, uint64_t gpu_end_ns, uint64_t when_ns) 698 + struct u_pacing_compositor *upc, int64_t frame_id, int64_t gpu_start_ns, int64_t gpu_end_ns, int64_t when_ns) 699 699 { 700 700 if (u_metrics_is_active()) { 701 701 struct u_metrics_system_gpu_info umgi = { ··· 710 710 } 711 711 712 712 static void 713 - pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t last_vblank_ns) 713 + pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, int64_t last_vblank_ns) 714 714 { 715 715 /* 716 716 * This is a no-op, here in case display control is used at the ··· 719 719 } 720 720 721 721 static void 722 - pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, uint64_t present_to_display_offset_ns) 722 + pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, int64_t present_to_display_offset_ns) 723 723 { 724 724 struct pacing_compositor *pc = pacing_compositor(upc); 725 725 ··· 750 750 }; 751 751 752 752 xrt_result_t 753 - u_pc_display_timing_create(uint64_t estimated_frame_period_ns, 753 + u_pc_display_timing_create(int64_t estimated_frame_period_ns, 754 754 const struct u_pc_display_timing_config *config, 755 755 struct u_pacing_compositor **out_upc) 756 756 {
+57 -57
src/xrt/auxiliary/util/u_pacing_compositor_fake.c
··· 45 45 int64_t frame_id; 46 46 47 47 //! When should the compositor wake up. Set in `pc_predict`. 48 - uint64_t predicted_wake_up_time_ns; 48 + int64_t predicted_wake_up_time_ns; 49 49 50 50 //! When should the compositor present the frame. 51 - uint64_t predicted_present_time_ns; 51 + int64_t predicted_present_time_ns; 52 52 53 53 //! When should the frame be displayed. 54 - uint64_t predicted_display_time_ns; 54 + int64_t predicted_display_time_ns; 55 55 56 56 //! The period that the pacer used for this frame. 57 - uint64_t predicted_display_period_ns; 57 + int64_t predicted_display_period_ns; 58 58 59 59 //! When this frame was last used for a prediction. Set in `pc_predict`. 60 - uint64_t when_predict_ns; 60 + int64_t when_predict_ns; 61 61 62 62 /*! 63 63 * When the compositor woke up after its equivalent of wait_frame. 64 64 * Set in `pc_mark_point` with `U_TIMING_POINT_WAKE_UP`. 65 65 */ 66 - uint64_t when_woke_ns; 66 + int64_t when_woke_ns; 67 67 68 68 /*! 69 69 * When the compositor began rendering a frame. Set in `pc_mark_point` 70 70 * with `U_TIMING_POINT_BEGIN`. 71 71 */ 72 - uint64_t when_began_ns; 72 + int64_t when_began_ns; 73 73 74 74 /*! 75 75 * When the compositor began submitting the work to the GPU, after 76 76 * it completed building the command buffers. Set in `pc_mark_point` 77 77 * with `U_TIMING_POINT_SUBMIT_BEGIN`. 78 78 */ 79 - uint64_t when_submit_began_ns; 79 + int64_t when_submit_began_ns; 80 80 81 81 /*! 82 82 * When the compositor completed submitting the work to the GPU. Set in 83 83 * `pc_mark_point` with `U_TIMING_POINT_SUBMIT_END`. 84 84 */ 85 - uint64_t when_submit_end_ns; 85 + int64_t when_submit_end_ns; 86 86 }; 87 87 88 88 /*! ··· 97 97 /*! 98 98 * The periodicity of the display. 99 99 */ 100 - uint64_t frame_period_ns; 100 + int64_t frame_period_ns; 101 101 102 102 /*! 103 103 * When the last frame was presented, not displayed. 104 104 */ 105 - uint64_t last_present_time_ns; 105 + int64_t last_present_time_ns; 106 106 107 107 /*! 108 108 * Very often the present time that we get from the system is only when ··· 112 112 struct u_var_draggable_f32 present_to_display_offset_ms; 113 113 114 114 //! The amount of time that the application needs to render frame. 115 - uint64_t comp_time_ns; 115 + int64_t comp_time_ns; 116 116 117 117 //! This won't run out, trust me. 118 118 int64_t frame_id_generator; ··· 165 165 return f; 166 166 } 167 167 168 - static uint64_t 169 - predict_next_frame_present_time(struct fake_timing *ft, uint64_t now_ns) 168 + static int64_t 169 + predict_next_frame_present_time(struct fake_timing *ft, int64_t now_ns) 170 170 { 171 - uint64_t time_needed_ns = ft->comp_time_ns; 172 - uint64_t predicted_present_time_ns = ft->last_present_time_ns + ft->frame_period_ns; 171 + int64_t time_needed_ns = ft->comp_time_ns; 172 + int64_t predicted_present_time_ns = ft->last_present_time_ns + ft->frame_period_ns; 173 173 174 174 while (now_ns + time_needed_ns > predicted_present_time_ns) { 175 175 predicted_present_time_ns += ft->frame_period_ns; ··· 178 178 return predicted_present_time_ns; 179 179 } 180 180 181 - static uint64_t 182 - calc_display_time(struct fake_timing *ft, uint64_t present_time_ns) 181 + static int64_t 182 + calc_display_time(struct fake_timing *ft, int64_t present_time_ns) 183 183 { 184 184 double offset_ms = ft->present_to_display_offset_ms.val; 185 - uint64_t offset_ns = time_ms_f_to_ns(offset_ms); 185 + int64_t offset_ns = time_ms_f_to_ns(offset_ms); 186 186 return present_time_ns + offset_ns; 187 187 } 188 188 189 - static uint64_t 190 - get_percent_of_time(uint64_t time_ns, uint32_t fraction_percent) 189 + static int64_t 190 + get_percent_of_time(int64_t time_ns, uint32_t fraction_percent) 191 191 { 192 192 double fraction = (double)fraction_percent / 100.0; 193 193 return time_s_to_ns(time_ns_to_s(time_ns) * fraction); ··· 224 224 return; 225 225 } 226 226 227 - uint64_t cpu_ns = f->when_began_ns - f->when_woke_ns; 228 - uint64_t draw_ns = f->when_submit_began_ns - f->when_began_ns; 229 - uint64_t submit_ns = f->when_submit_end_ns - f->when_submit_began_ns; 227 + int64_t cpu_ns = f->when_began_ns - f->when_woke_ns; 228 + int64_t draw_ns = f->when_submit_began_ns - f->when_began_ns; 229 + int64_t submit_ns = f->when_submit_end_ns - f->when_submit_began_ns; 230 230 231 231 bool full = false; 232 232 full |= u_ls_ns_add(&ft->cpu, cpu_ns); ··· 239 239 } 240 240 241 241 static void 242 - calc_gpu_stats(struct fake_timing *ft, struct frame *f, uint64_t gpu_start_ns, uint64_t gpu_end_ns) 242 + calc_gpu_stats(struct fake_timing *ft, struct frame *f, int64_t gpu_start_ns, int64_t gpu_end_ns) 243 243 { 244 244 if (!debug_get_bool_option_live_stats()) { 245 245 return; 246 246 } 247 247 248 - uint64_t then_ns = f->when_submit_began_ns; 249 - uint64_t delay_ns = gpu_start_ns > then_ns ? gpu_start_ns - then_ns : 0; 250 - uint64_t gpu_ns = gpu_end_ns - gpu_start_ns; 251 - uint64_t frame_ns = gpu_end_ns - f->when_woke_ns; 248 + int64_t then_ns = f->when_submit_began_ns; 249 + int64_t delay_ns = gpu_start_ns > then_ns ? gpu_start_ns - then_ns : 0; 250 + int64_t gpu_ns = gpu_end_ns - gpu_start_ns; 251 + int64_t frame_ns = gpu_end_ns - f->when_woke_ns; 252 252 253 253 bool full = false; 254 254 full |= u_ls_ns_add(&ft->gpu, gpu_ns); ··· 269 269 270 270 static void 271 271 pc_predict(struct u_pacing_compositor *upc, 272 - uint64_t now_ns, 272 + int64_t now_ns, 273 273 int64_t *out_frame_id, 274 - uint64_t *out_wake_up_time_ns, 275 - uint64_t *out_desired_present_time_ns, 276 - uint64_t *out_present_slop_ns, 277 - uint64_t *out_predicted_display_time_ns, 278 - uint64_t *out_predicted_display_period_ns, 279 - uint64_t *out_min_display_period_ns) 274 + int64_t *out_wake_up_time_ns, 275 + int64_t *out_desired_present_time_ns, 276 + int64_t *out_present_slop_ns, 277 + int64_t *out_predicted_display_time_ns, 278 + int64_t *out_predicted_display_period_ns, 279 + int64_t *out_min_display_period_ns) 280 280 { 281 281 struct fake_timing *ft = fake_timing(upc); 282 282 283 283 struct frame *f = get_new_frame(ft); 284 284 285 285 int64_t frame_id = f->frame_id; 286 - uint64_t desired_present_time_ns = predict_next_frame_present_time(ft, now_ns); 287 - uint64_t predicted_display_time_ns = calc_display_time(ft, desired_present_time_ns); 286 + int64_t desired_present_time_ns = predict_next_frame_present_time(ft, now_ns); 287 + int64_t predicted_display_time_ns = calc_display_time(ft, desired_present_time_ns); 288 288 289 - uint64_t wake_up_time_ns = desired_present_time_ns - ft->comp_time_ns; 290 - uint64_t present_slop_ns = U_TIME_HALF_MS_IN_NS; 291 - uint64_t predicted_display_period_ns = ft->frame_period_ns; 292 - uint64_t min_display_period_ns = ft->frame_period_ns; 289 + int64_t wake_up_time_ns = desired_present_time_ns - ft->comp_time_ns; 290 + int64_t present_slop_ns = U_TIME_HALF_MS_IN_NS; 291 + int64_t predicted_display_period_ns = ft->frame_period_ns; 292 + int64_t min_display_period_ns = ft->frame_period_ns; 293 293 294 294 // Set the frame info. 295 295 f->predicted_wake_up_time_ns = wake_up_time_ns; ··· 322 322 } 323 323 324 324 static void 325 - pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, uint64_t when_ns) 325 + pc_mark_point(struct u_pacing_compositor *upc, enum u_timing_point point, int64_t frame_id, int64_t when_ns) 326 326 { 327 327 struct fake_timing *ft = fake_timing(upc); 328 328 struct frame *f = get_frame_or_null(ft, frame_id); ··· 348 348 static void 349 349 pc_info(struct u_pacing_compositor *upc, 350 350 int64_t frame_id, 351 - uint64_t desired_present_time_ns, 352 - uint64_t actual_present_time_ns, 353 - uint64_t earliest_present_time_ns, 354 - uint64_t present_margin_ns, 355 - uint64_t when_ns) 351 + int64_t desired_present_time_ns, 352 + int64_t actual_present_time_ns, 353 + int64_t earliest_present_time_ns, 354 + int64_t present_margin_ns, 355 + int64_t when_ns) 356 356 { 357 357 /* 358 358 * The compositor might call this function because it selected the ··· 362 362 363 363 static void 364 364 pc_info_gpu( 365 - struct u_pacing_compositor *upc, int64_t frame_id, uint64_t gpu_start_ns, uint64_t gpu_end_ns, uint64_t when_ns) 365 + struct u_pacing_compositor *upc, int64_t frame_id, int64_t gpu_start_ns, int64_t gpu_end_ns, int64_t when_ns) 366 366 { 367 367 struct fake_timing *ft = fake_timing(upc); 368 368 ··· 396 396 #endif 397 397 398 398 #ifdef U_TRACE_TRACY 399 - uint64_t diff_ns = gpu_end_ns - gpu_start_ns; 399 + int64_t diff_ns = gpu_end_ns - gpu_start_ns; 400 400 TracyCPlot("Compositor GPU(ms)", time_ns_to_ms_f(diff_ns)); 401 401 #endif 402 402 } 403 403 404 404 static void 405 - pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, uint64_t last_vblank_ns) 405 + pc_update_vblank_from_display_control(struct u_pacing_compositor *upc, int64_t last_vblank_ns) 406 406 { 407 407 struct fake_timing *ft = fake_timing(upc); 408 408 ··· 411 411 } 412 412 413 413 static void 414 - pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, uint64_t present_to_display_offset_ns) 414 + pc_update_present_offset(struct u_pacing_compositor *upc, int64_t frame_id, int64_t present_to_display_offset_ns) 415 415 { 416 416 struct fake_timing *ft = fake_timing(upc); 417 417 ··· 441 441 */ 442 442 443 443 xrt_result_t 444 - u_pc_fake_create(uint64_t estimated_frame_period_ns, uint64_t now_ns, struct u_pacing_compositor **out_upc) 444 + u_pc_fake_create(int64_t estimated_frame_period_ns, int64_t now_ns, struct u_pacing_compositor **out_upc) 445 445 { 446 446 struct fake_timing *ft = U_TYPED_CALLOC(struct fake_timing); 447 447 ft->base.predict = pc_predict; ··· 479 479 480 480 // Or at least a certain amount of time. 481 481 float min_comp_time_ms_f = debug_get_float_option_min_comp_time_ms(); 482 - uint64_t min_comp_time_ns = time_ms_f_to_ns(min_comp_time_ms_f); 482 + int64_t min_comp_time_ns = time_ms_f_to_ns(min_comp_time_ms_f); 483 483 484 484 if (ft->comp_time_ns < min_comp_time_ns) { 485 485 ft->comp_time_ns = min_comp_time_ns; ··· 491 491 // U variable tracking. 492 492 u_var_add_root(ft, "Compositor timing info", true); 493 493 u_var_add_draggable_f32(ft, &ft->present_to_display_offset_ms, "Present to display offset(ms)"); 494 - u_var_add_ro_u64(ft, &ft->frame_period_ns, "Frame period(ns)"); 495 - u_var_add_ro_u64(ft, &ft->comp_time_ns, "Compositor time(ns)"); 496 - u_var_add_ro_u64(ft, &ft->last_present_time_ns, "Last present time(ns)"); 494 + u_var_add_ro_i64(ft, &ft->frame_period_ns, "Frame period(ns)"); 495 + u_var_add_ro_i64(ft, &ft->comp_time_ns, "Compositor time(ns)"); 496 + u_var_add_ro_i64(ft, &ft->last_present_time_ns, "Last present time(ns)"); 497 497 498 498 // Return value. 499 499 *out_upc = &ft->base;
+24 -24
tests/tests_pacing.cpp
··· 25 25 26 26 namespace { 27 27 28 - uint64_t 29 - getNextPresentAfterTimestampAndKnownPresent(uint64_t timestamp_ns, uint64_t known_present_ns) 28 + int64_t 29 + getNextPresentAfterTimestampAndKnownPresent(int64_t timestamp_ns, int64_t known_present_ns) 30 30 { 31 31 32 32 while (known_present_ns < timestamp_ns) { ··· 34 34 } 35 35 return known_present_ns; 36 36 } 37 - uint64_t 38 - getPresentBefore(uint64_t timestamp_ns, uint64_t known_present_ns) 37 + int64_t 38 + getPresentBefore(int64_t timestamp_ns, int64_t known_present_ns) 39 39 { 40 40 41 41 while (known_present_ns >= timestamp_ns && known_present_ns > frame_interval_ns.count()) { ··· 43 43 } 44 44 return known_present_ns; 45 45 } 46 - uint64_t 47 - getNextPresentAfterTimestamp(uint64_t timestamp_ns, uint64_t known_present_ns) 46 + int64_t 47 + getNextPresentAfterTimestamp(int64_t timestamp_ns, int64_t known_present_ns) 48 48 { 49 49 auto present_before_ns = getPresentBefore(timestamp_ns, known_present_ns); 50 50 return getNextPresentAfterTimestampAndKnownPresent(timestamp_ns, present_before_ns); ··· 53 53 struct CompositorPredictions 54 54 { 55 55 int64_t frame_id{0}; 56 - uint64_t wake_up_time_ns{0}; 57 - uint64_t desired_present_time_ns{0}; 58 - uint64_t present_slop_ns{0}; 59 - uint64_t predicted_display_time_ns{0}; 60 - uint64_t predicted_display_period_ns{0}; 61 - uint64_t min_display_period_ns{0}; 56 + int64_t wake_up_time_ns{0}; 57 + int64_t desired_present_time_ns{0}; 58 + int64_t present_slop_ns{0}; 59 + int64_t predicted_display_time_ns{0}; 60 + int64_t predicted_display_period_ns{0}; 61 + int64_t min_display_period_ns{0}; 62 62 }; 63 63 } // namespace 64 64 65 65 static void 66 - basicPredictionConsistencyChecks(uint64_t now_ns, CompositorPredictions const &predictions) 66 + basicPredictionConsistencyChecks(int64_t now_ns, CompositorPredictions const &predictions) 67 67 { 68 68 INFO(predictions.frame_id); 69 69 INFO(now_ns); ··· 79 79 80 80 struct SimulatedDisplayTimingData 81 81 { 82 - SimulatedDisplayTimingData(int64_t id, uint64_t desired_present_time, uint64_t gpu_finish, uint64_t now) 82 + SimulatedDisplayTimingData(int64_t id, int64_t desired_present_time, int64_t gpu_finish, int64_t now) 83 83 : frame_id(id), desired_present_time_ns(desired_present_time), 84 84 actual_present_time_ns(getNextPresentAfterTimestampAndKnownPresent(gpu_finish, desired_present_time)), 85 85 earliest_present_time_ns(getNextPresentAfterTimestamp(gpu_finish, desired_present_time)), ··· 87 87 {} 88 88 89 89 int64_t frame_id; 90 - uint64_t desired_present_time_ns; 91 - uint64_t actual_present_time_ns; 92 - uint64_t earliest_present_time_ns; 93 - uint64_t present_margin_ns; 94 - uint64_t now_ns; 90 + int64_t desired_present_time_ns; 91 + int64_t actual_present_time_ns; 92 + int64_t earliest_present_time_ns; 93 + int64_t present_margin_ns; 94 + int64_t now_ns; 95 95 void 96 96 call_u_pc_info(u_pacing_compositor *upc) const 97 97 { ··· 116 116 117 117 //! Process all simulated timing data in the queue that should be processed by now. 118 118 static void 119 - processDisplayTimingQueue(SimulatedDisplayTimingQueue &display_timing_queue, uint64_t now_ns, u_pacing_compositor *upc) 119 + processDisplayTimingQueue(SimulatedDisplayTimingQueue &display_timing_queue, int64_t now_ns, u_pacing_compositor *upc) 120 120 { 121 121 while (!display_timing_queue.empty() && display_timing_queue.top().now_ns <= now_ns) { 122 122 display_timing_queue.top().call_u_pc_info(upc); ··· 124 124 } 125 125 } 126 126 //! Process all remaining simulated timing data in the queue and return the timestamp of the last one. 127 - static uint64_t 128 - drainDisplayTimingQueue(SimulatedDisplayTimingQueue &display_timing_queue, uint64_t now_ns, u_pacing_compositor *upc) 127 + static int64_t 128 + drainDisplayTimingQueue(SimulatedDisplayTimingQueue &display_timing_queue, int64_t now_ns, u_pacing_compositor *upc) 129 129 { 130 130 while (!display_timing_queue.empty()) { 131 131 now_ns = display_timing_queue.top().now_ns; ··· 139 139 doFrame(SimulatedDisplayTimingQueue &display_timing_queue, 140 140 u_pacing_compositor *upc, 141 141 MockClock &clock, 142 - uint64_t wake_time_ns, 143 - uint64_t desired_present_time_ns, 142 + int64_t wake_time_ns, 143 + int64_t desired_present_time_ns, 144 144 int64_t frame_id, 145 145 unanoseconds wake_delay, 146 146 unanoseconds begin_delay,
+3 -86
tests/time_utils.hpp
··· 8 8 9 9 #pragma once 10 10 11 - #include <iostream> 12 11 #include <chrono> 13 - #include <sstream> 14 - #include <functional> 15 - #include <iomanip> 16 - 17 - using unanoseconds = std::chrono::duration<uint64_t, std::nano>; 18 12 19 - 20 - template <typename T> 21 - static inline std::string 22 - stringifyNanos(std::chrono::duration<T, std::nano> value) 23 - { 24 - using namespace std::chrono; 25 - std::ostringstream oss; 26 - auto sec = duration_cast<duration<T>>(value); 27 - if (duration<T, std::nano>(sec) == value) { 28 - oss << sec.count() << "s"; 29 - return oss.str(); 30 - } 31 - 32 - auto millis = duration_cast<duration<T, std::milli>>(value); 33 - if (duration<T, std::nano>(millis) == value) { 34 - oss << millis.count() << "ms"; 35 - return oss.str(); 36 - } 37 - 38 - auto micros = duration_cast<duration<T, std::micro>>(value); 39 - if (duration<T, std::nano>(micros) == value) { 40 - oss << micros.count() << "us"; 41 - return oss.str(); 42 - } 43 - 44 - oss << value.count() << "ns"; 45 - return oss.str(); 46 - } 47 - 48 - static inline std::string 49 - stringifyTimePoint(std::chrono::steady_clock::time_point tp) 50 - { 51 - auto dur = tp.time_since_epoch(); 52 - auto hr = std::chrono::duration_cast<std::chrono::hours>(dur); 53 - dur -= hr; 54 - auto sec = std::chrono::duration_cast<std::chrono::seconds>(dur); 55 - dur -= sec; 56 - std::ostringstream oss; 57 - if (hr.count() > 0) { 58 - oss << hr.count() << ":"; 59 - } 60 - oss << sec.count() << "."; 61 - using three_commas = 62 - std::ratio_multiply<std::ratio<1, 1000>, std::ratio_multiply<std::ratio<1, 1000>, std::ratio<1, 1000>>>; 63 - static_assert(std::ratio_equal<three_commas, std::nano>::value); 64 - // 9 because of the preceding static assert: there's no compile-time rational log10? :-O 65 - oss << std::setfill('0') << std::setw(9); 66 - oss << dur.count(); 67 - return oss.str(); 68 - } 69 - 70 - namespace Catch { 71 - template <> struct StringMaker<unanoseconds> 72 - { 73 - static std::string 74 - convert(unanoseconds const &value) 75 - { 76 - return stringifyNanos(value); 77 - } 78 - }; 79 - template <> struct StringMaker<std::chrono::nanoseconds> 80 - { 81 - static std::string 82 - convert(std::chrono::nanoseconds const &value) 83 - { 84 - return stringifyNanos(value); 85 - } 86 - }; 87 - template <> struct StringMaker<std::chrono::steady_clock::time_point> 88 - { 89 - static std::string 90 - convert(std::chrono::steady_clock::time_point const &value) 91 - { 92 - return stringifyTimePoint(value); 93 - } 94 - }; 95 - } // namespace Catch 96 - 13 + using unanoseconds = std::chrono::duration<int64_t, std::nano>; 97 14 98 15 class MockClock 99 16 { 100 17 public: 101 - uint64_t 18 + int64_t 102 19 now() const noexcept 103 20 { 104 21 return std::chrono::duration_cast<unanoseconds>(now_.time_since_epoch()).count(); ··· 117 34 } 118 35 119 36 void 120 - advance_to(uint64_t timestamp_ns) 37 + advance_to(int64_t timestamp_ns) 121 38 { 122 39 CHECK(now() <= timestamp_ns); 123 40 now_ = std::chrono::steady_clock::time_point(