UI: add a preference for the number of samples used for FPS playback
This was hard coded to 8, which can still result in a number that jitters making the overall FPS difficult to measure. The default is still 8, but this is now a preference that can be increased for values that don't jitter as much.
This commit is contained in:
@@ -108,6 +108,7 @@ const UserDef U_default = {
|
||||
.gp_euclideandist = 2,
|
||||
.gp_eraser = 25,
|
||||
.gp_settings = 0,
|
||||
.playback_fps_samples = 8,
|
||||
#ifdef __APPLE__
|
||||
.gpu_backend = GPU_BACKEND_METAL,
|
||||
#else
|
||||
|
||||
@@ -720,6 +720,9 @@ class USERPREF_PT_viewport_display(ViewportPanel, CenterAlignMixIn, Panel):
|
||||
col.prop(view, "show_object_info", text="Object Info")
|
||||
col.prop(view, "show_view_name", text="View Name")
|
||||
col.prop(view, "show_playback_fps", text="Playback Frame Rate (FPS)")
|
||||
row = col.row()
|
||||
row.active = view.show_playback_fps
|
||||
row.prop(view, "playback_fps_samples", text="Frame Rate Samples")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ extern "C" {
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 17
|
||||
#define BLENDER_FILE_SUBVERSION 18
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
||||
@@ -852,6 +852,10 @@ void blo_do_versions_userdef(UserDef *userdef)
|
||||
userdef->node_preview_res = 120;
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(400, 18)) {
|
||||
userdef->playback_fps_samples = 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
|
||||
@@ -43,20 +43,24 @@ enum {
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
|
||||
#define REDRAW_FRAME_AVERAGE 8
|
||||
|
||||
/**
|
||||
* For playback frame-rate info stored during runtime as `scene->fps_info`.
|
||||
*/
|
||||
struct ScreenFrameRateInfo {
|
||||
double redrawtime;
|
||||
double lredrawtime;
|
||||
float redrawtimes_fps[REDRAW_FRAME_AVERAGE];
|
||||
short redrawtime_index;
|
||||
|
||||
/** The target FPS, use to reset on change. */
|
||||
float fps_target;
|
||||
/** Final result, ignore when -1.0. */
|
||||
float fps_average;
|
||||
|
||||
int redrawtimes_index;
|
||||
int redrawtimes_num;
|
||||
int redrawtimes_num_set;
|
||||
|
||||
/** Over allocate. */
|
||||
float redrawtimes_fps[0];
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
|
||||
@@ -1694,22 +1694,30 @@ void ED_scene_fps_average_accumulate(Scene *scene, const double ltime)
|
||||
|
||||
/* Playback running. */
|
||||
const float fps_target = float(FPS);
|
||||
ScreenFrameRateInfo *fpsi = static_cast<ScreenFrameRateInfo *>(scene->fps_info);
|
||||
|
||||
/* Reset when the target FPS changes.
|
||||
* Needed redraw times from when a different FPS was set do not contribute
|
||||
* to an average that is over/under the new target. */
|
||||
if (fpsi && (fpsi->fps_target != fps_target)) {
|
||||
MEM_freeN(fpsi);
|
||||
fpsi = nullptr;
|
||||
scene->fps_info = nullptr;
|
||||
ScreenFrameRateInfo *fpsi = static_cast<ScreenFrameRateInfo *>(scene->fps_info);
|
||||
const int redrawtimes_num = U.playback_fps_samples ? U.playback_fps_samples :
|
||||
max_ii(1, int(ceilf(fps_target)));
|
||||
|
||||
if (fpsi) {
|
||||
/* Reset when the target FPS changes.
|
||||
* Needed redraw times from when a different FPS was set do not contribute
|
||||
* to an average that is over/under the new target. */
|
||||
if ((fpsi->fps_target != fps_target) || (fpsi->redrawtimes_num != redrawtimes_num)) {
|
||||
MEM_freeN(fpsi);
|
||||
fpsi = nullptr;
|
||||
scene->fps_info = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there isn't any info, initialize it first. */
|
||||
if (fpsi == nullptr) {
|
||||
fpsi = static_cast<ScreenFrameRateInfo *>(
|
||||
scene->fps_info = MEM_callocN(sizeof(ScreenFrameRateInfo), __func__));
|
||||
scene->fps_info = MEM_callocN(sizeof(ScreenFrameRateInfo) + (sizeof(float) * redrawtimes_num),
|
||||
__func__);
|
||||
fpsi = static_cast<ScreenFrameRateInfo *>(scene->fps_info);
|
||||
fpsi->fps_target = fps_target;
|
||||
fpsi->redrawtimes_num = redrawtimes_num;
|
||||
fpsi->redrawtimes_num_set = 0;
|
||||
}
|
||||
|
||||
/* Update the values. */
|
||||
@@ -1738,22 +1746,23 @@ bool ED_scene_fps_average_calc(const Scene *scene)
|
||||
return true;
|
||||
}
|
||||
|
||||
fpsi->redrawtimes_fps[fpsi->redrawtime_index] = float(1.0 /
|
||||
(fpsi->lredrawtime - fpsi->redrawtime));
|
||||
if (fpsi->redrawtimes_index >= fpsi->redrawtimes_num) {
|
||||
fpsi->redrawtimes_index = 0;
|
||||
}
|
||||
|
||||
/* Doing an average for a more robust calculation. */
|
||||
fpsi->redrawtimes_fps[fpsi->redrawtimes_index] = float(1.0 /
|
||||
(fpsi->lredrawtime - fpsi->redrawtime));
|
||||
fpsi->redrawtimes_index++;
|
||||
if (fpsi->redrawtimes_index > fpsi->redrawtimes_num_set) {
|
||||
fpsi->redrawtimes_num_set = fpsi->redrawtimes_index;
|
||||
}
|
||||
BLI_assert(fpsi->redrawtimes_num_set > 0);
|
||||
float fps = 0.0f;
|
||||
int tot = 0;
|
||||
for (int i = 0; i < REDRAW_FRAME_AVERAGE; i++) {
|
||||
if (fpsi->redrawtimes_fps[i]) {
|
||||
fps += fpsi->redrawtimes_fps[i];
|
||||
tot++;
|
||||
}
|
||||
for (int i = 0; i < fpsi->redrawtimes_num_set; i++) {
|
||||
fps += fpsi->redrawtimes_fps[i];
|
||||
}
|
||||
if (tot) {
|
||||
fpsi->redrawtime_index = (fpsi->redrawtime_index + 1) % REDRAW_FRAME_AVERAGE;
|
||||
fps = fps / tot;
|
||||
}
|
||||
fpsi->fps_average = fps;
|
||||
fpsi->fps_average = fps / float(fpsi->redrawtimes_num_set);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -923,7 +923,10 @@ typedef struct UserDef {
|
||||
/** #eGPUBackendType */
|
||||
short gpu_backend;
|
||||
|
||||
char _pad7[4];
|
||||
/** Number of samples for FPS display calculations. */
|
||||
uchar playback_fps_samples;
|
||||
|
||||
char _pad7[3];
|
||||
|
||||
/** Private, defaults to 20 for 72 DPI setting. */
|
||||
short widget_unit;
|
||||
|
||||
@@ -4833,6 +4833,16 @@ static void rna_def_userdef_view(BlenderRNA *brna)
|
||||
"overlay while animation is played back");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||
|
||||
prop = RNA_def_property(srna, "playback_fps_samples", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, nullptr, "playback_fps_samples");
|
||||
RNA_def_property_range(prop, 0, 200);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"FPS Average Samples",
|
||||
"The number of frames to use for calculating FPS average. "
|
||||
"Zero to calculate this automatically, where the number of samples matches the target FPS");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||
|
||||
USERDEF_TAG_DIRTY_PROPERTY_UPDATE_DISABLE;
|
||||
prop = RNA_def_property(srna, "show_addons_enabled_only", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(
|
||||
|
||||
Reference in New Issue
Block a user