The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

st/gui: Add compositor frame timing graph to debug ui

+178
+28
src/xrt/auxiliary/util/u_var.h
··· 15 15 extern "C" { 16 16 #endif 17 17 18 + struct u_var_f32_arr 19 + { 20 + void *data; 21 + int *index_ptr; 22 + int length; 23 + }; 24 + 25 + struct u_var_timing 26 + { 27 + struct u_var_f32_arr values; 28 + float reference_timing; 29 + 30 + // if false, reference_timing will be the bottom of the graph 31 + bool center_reference_timing; 32 + 33 + // how many units the graph expands by default 34 + float range; 35 + 36 + // a string describing the unit used 37 + char *unit; 38 + 39 + // rescale graph's value range when value exceeds range 40 + bool dynamic_rescale; 41 + }; 18 42 19 43 struct xrt_frame_sink; 20 44 ··· 34 58 U_VAR_KIND_U8, 35 59 U_VAR_KIND_I32, 36 60 U_VAR_KIND_F32, 61 + U_VAR_KIND_F32_ARR, 62 + U_VAR_KIND_TIMING, 37 63 U_VAR_KIND_VEC3_I32, 38 64 U_VAR_KIND_VEC3_F32, 39 65 U_VAR_KIND_POSE, ··· 113 139 ADD_FUNC(u8, uint8_t, U8) \ 114 140 ADD_FUNC(i32, int32_t, I32) \ 115 141 ADD_FUNC(f32, float, F32) \ 142 + ADD_FUNC(f32_arr, struct u_var_f32_arr, F32_ARR) \ 143 + ADD_FUNC(f32_timing, struct u_var_timing, TIMING) \ 116 144 ADD_FUNC(vec3_i32, struct xrt_vec3_i32, VEC3_I32) \ 117 145 ADD_FUNC(vec3_f32, struct xrt_vec3, VEC3_F32) \ 118 146 ADD_FUNC(pose, struct xrt_pose, POSE) \
+73
src/xrt/compositor/main/comp_compositor.c
··· 60 60 #include <unistd.h> 61 61 #include <math.h> 62 62 63 + #include "util/u_var.h" 64 + 63 65 /*! 64 66 */ 65 67 static void ··· 96 98 if (vk->instance != VK_NULL_HANDLE) { 97 99 vk->vkDestroyInstance(vk->instance, NULL); 98 100 vk->instance = VK_NULL_HANDLE; 101 + } 102 + 103 + if (c->compositor_frame_times.debug_var) { 104 + free(c->compositor_frame_times.debug_var); 99 105 } 100 106 101 107 free(c); ··· 230 236 } 231 237 232 238 static void 239 + compositor_add_frame_timing(struct comp_compositor *c) 240 + { 241 + int last_index = c->compositor_frame_times.index; 242 + 243 + c->compositor_frame_times.index++; 244 + c->compositor_frame_times.index %= NUM_FRAME_TIMES; 245 + 246 + // update fps only once every FPS_NUM_TIMINGS 247 + if (c->compositor_frame_times.index == 0) { 248 + float total_s = 0; 249 + 250 + // frame *timings* are durations between *times* 251 + int NUM_FRAME_TIMINGS = NUM_FRAME_TIMES - 1; 252 + 253 + for (int i = 0; i < NUM_FRAME_TIMINGS; i++) { 254 + uint64_t frametime_ns = 255 + c->compositor_frame_times.times_ns[i + 1] - 256 + c->compositor_frame_times.times_ns[i]; 257 + float frametime_s = 258 + frametime_ns * 1. / 1000. * 1. / 1000. * 1. / 1000.; 259 + total_s += frametime_s; 260 + } 261 + float avg_frametime_s = total_s / ((float)NUM_FRAME_TIMINGS); 262 + c->compositor_frame_times.fps = 1. / avg_frametime_s; 263 + } 264 + 265 + c->compositor_frame_times.times_ns[c->compositor_frame_times.index] = 266 + os_monotonic_get_ns(); 267 + 268 + uint64_t diff = c->compositor_frame_times 269 + .times_ns[c->compositor_frame_times.index] - 270 + c->compositor_frame_times.times_ns[last_index]; 271 + c->compositor_frame_times.timings_ms[c->compositor_frame_times.index] = 272 + (float)diff * 1. / 1000. * 1. / 1000.; 273 + } 274 + 275 + static void 233 276 compositor_end_frame(struct xrt_compositor *xc, 234 277 enum xrt_blend_mode blend_mode, 235 278 struct xrt_swapchain **xscs, ··· 251 294 } else { 252 295 COMP_ERROR(c, "non-stereo rendering not supported"); 253 296 } 297 + 298 + compositor_add_frame_timing(c); 254 299 255 300 // Record the time of this frame. 256 301 c->last_frame_time_ns = os_monotonic_get_ns(); ··· 802 847 // clang-format on 803 848 804 849 COMP_DEBUG(c, "Done %p", (void *)c); 850 + 851 + 852 + u_var_add_root(c, "Compositor", true); 853 + u_var_add_ro_f32(c, &c->compositor_frame_times.fps, "FPS (Compositor)"); 854 + 855 + struct u_var_timing *ft = U_CALLOC_WITH_CAST( 856 + struct u_var_timing, sizeof(struct u_var_timing)); 857 + 858 + float target_frame_time_ms = 859 + c->settings.nominal_frame_interval_ns * 1. / 1000. * 1. / 1000.; 860 + 861 + uint64_t now = os_monotonic_get_ns(); 862 + for (int i = 0; i < NUM_FRAME_TIMES; i++) { 863 + c->compositor_frame_times.times_ns[i] = now + i; 864 + } 865 + ft->values.data = c->compositor_frame_times.timings_ms; 866 + ft->values.length = NUM_FRAME_TIMES; 867 + ft->values.index_ptr = &c->compositor_frame_times.index; 868 + 869 + ft->reference_timing = target_frame_time_ms; 870 + ft->range = 10.f; 871 + ft->unit = "ms"; 872 + ft->dynamic_rescale = false; 873 + ft->center_reference_timing = true; 874 + 875 + u_var_add_f32_timing(c, ft, "Frame Times (Compositor)"); 876 + 877 + c->compositor_frame_times.debug_var = ft; 805 878 806 879 return &c->base; 807 880 }
+19
src/xrt/compositor/main/comp_compositor.h
··· 20 20 extern "C" { 21 21 #endif 22 22 23 + #define NUM_FRAME_TIMES 50 23 24 24 25 /* 25 26 * ··· 103 104 104 105 //! The time our compositor needs to do rendering 105 106 int64_t frame_overhead_ns; 107 + 108 + struct 109 + { 110 + //! Current Index for times_ns. 111 + int index; 112 + 113 + //! Timestamps of last-rendered (immersive) frames. 114 + int64_t times_ns[NUM_FRAME_TIMES]; 115 + 116 + //! Frametimes between last-rendered (immersive) frames. 117 + float timings_ms[NUM_FRAME_TIMES]; 118 + 119 + //! Average FPS of last NUM_FRAME_TIMES rendered frames. 120 + float fps; 121 + 122 + struct u_var_timing *debug_var; 123 + } compositor_frame_times; 124 + 106 125 /*! 107 126 * @brief Estimated rendering time per frame of the application. 108 127 *
+1
src/xrt/state_trackers/gui/CMakeLists.txt
··· 12 12 gui_scene_main_menu.c 13 13 gui_scene_video.c 14 14 ../../../external/imgui/cimgui.cpp 15 + ../../../external/imgui_monado/imgui_monado.cpp 15 16 ../../../external/imgui/cimgui.h 16 17 ../../../external/imgui/imconfig.h 17 18 ../../../external/imgui/imgui.cpp
+55
src/xrt/state_trackers/gui/gui_scene_debug.c
··· 26 26 #include "gui_common.h" 27 27 #include "gui_imgui.h" 28 28 29 + #include "imgui_monado/cimgui_monado.h" 30 + 31 + #include <float.h> 29 32 30 33 struct debug_scene 31 34 { ··· 134 137 igBegin(name, NULL, 0); 135 138 } 136 139 140 + static float 141 + get_float_arr_val(void *_data, int _idx) 142 + { 143 + float *arr = _data; 144 + return arr[_idx]; 145 + } 146 + 137 147 static void 138 148 on_elem(const char *name, enum u_var_kind kind, void *ptr, void *priv) 139 149 { ··· 176 186 case U_VAR_KIND_F32: 177 187 igInputFloat(name, (float *)ptr, 1, 10, "%+f", i_flags); 178 188 break; 189 + case U_VAR_KIND_F32_ARR: { 190 + struct u_var_f32_arr *f32_arr = ptr; 191 + int index = *f32_arr->index_ptr; 192 + int length = f32_arr->length; 193 + float *arr = (float *)f32_arr->data; 194 + 195 + float w = igGetWindowContentRegionWidth(); 196 + ImVec2 graph_size = {w, 200}; 197 + 198 + float stats_min = FLT_MAX; 199 + float stats_max = FLT_MAX; 200 + 201 + igPlotLinesFnPtr(name, get_float_arr_val, arr, length, index, 202 + NULL, stats_min, stats_max, graph_size); 203 + break; 204 + } 205 + case U_VAR_KIND_TIMING: { 206 + struct u_var_timing *frametime_arr = ptr; 207 + struct u_var_f32_arr *f32_arr = &frametime_arr->values; 208 + int index = *f32_arr->index_ptr; 209 + int length = f32_arr->length; 210 + float *arr = (float *)f32_arr->data; 211 + 212 + float w = igGetWindowContentRegionWidth(); 213 + ImVec2 graph_size = {w, 200}; 214 + 215 + 216 + float stats_min = FLT_MAX; 217 + float stats_max = 0; 218 + 219 + for (int f = 0; f < length; f++) { 220 + if (arr[f] < stats_min) 221 + stats_min = arr[f]; 222 + if (arr[f] > stats_max) 223 + stats_max = arr[f]; 224 + } 225 + 226 + igPlotTimings(name, get_float_arr_val, arr, length, index, NULL, 227 + 0, stats_max, graph_size, 228 + frametime_arr->reference_timing, 229 + frametime_arr->center_reference_timing, 230 + frametime_arr->range, frametime_arr->unit, 231 + frametime_arr->dynamic_rescale); 232 + break; 233 + } 179 234 case U_VAR_KIND_VEC3_F32: 180 235 igInputFloat3(name, (float *)ptr, "%+f", i_flags); 181 236 break;
+2
src/xrt/state_trackers/gui/meson.build
··· 25 25 '../../../external/imgui/imstb_rectpack.h', 26 26 '../../../external/imgui/imstb_textedit.h', 27 27 '../../../external/imgui/imstb_truetype.h', 28 + '../../../external/imgui_monado/cimgui_monado.h', 29 + '../../../external/imgui_monado/imgui_monado.cpp' 28 30 ] 29 31 30 32 gui_deps = [aux, xrt_config_have]