1 /**************************************************************************
2 *
3 * Copyright (C) 2017 tint2 authors
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 **************************************************************************/
17
18 #include <stdlib.h>
19
20 #include "fps_distribution.h"
21
22 static float *fps_distribution = NULL;
23
init_fps_distribution()24 void init_fps_distribution()
25 {
26 // measure FPS with resolution:
27 // 0-59: 1 (60 samples)
28 // 60-199: 10 (14)
29 // 200-1,999: 25 (72)
30 // 1k-19,999: 1000 (19)
31 // 20x+: inf (1)
32 // => 166 samples
33 if (fps_distribution)
34 return;
35 fps_distribution = calloc(170, sizeof(float));
36 }
37
cleanup_fps_distribution()38 void cleanup_fps_distribution()
39 {
40 free(fps_distribution);
41 fps_distribution = NULL;
42 }
43
sample_fps(double fps)44 void sample_fps(double fps)
45 {
46 int fps_rounded = (int)(fps + 0.5);
47 int i = 1;
48 if (fps_rounded < 60) {
49 i += fps_rounded;
50 } else {
51 i += 60;
52 if (fps_rounded < 200) {
53 i += (fps_rounded - 60) / 10;
54 } else {
55 i += 14;
56 if (fps_rounded < 2000) {
57 i += (fps_rounded - 200) / 25;
58 } else {
59 i += 72;
60 if (fps_rounded < 20000) {
61 i += (fps_rounded - 2000) / 1000;
62 } else {
63 i += 20;
64 }
65 }
66 }
67 }
68 // fprintf(stderr, "tint2: fps = %.0f => i = %d\n", fps, i);
69 fps_distribution[i] += 1.;
70 fps_distribution[0] += 1.;
71 }
72
fps_compute_stats(double * low,double * median,double * high,double * samples)73 void fps_compute_stats(double *low, double *median, double *high, double *samples)
74 {
75 *median = *low = *high = *samples = -1;
76 if (!fps_distribution || fps_distribution[0] < 1)
77 return;
78 float total = fps_distribution[0];
79 *samples = (double)fps_distribution[0];
80 float cum_low = 0.05f * total;
81 float cum_median = 0.5f * total;
82 float cum_high = 0.95f * total;
83 float cum = 0;
84 for (int i = 1; i <= 166; i++) {
85 double value =
86 (i < 60) ? i : (i < 74) ? (60 + (i - 60) * 10) : (i < 146) ? (200 + (i - 74) * 25)
87 : (i < 165) ? (2000 + (i - 146) * 1000) : 20000;
88 // fprintf(stderr, "tint2: %6.0f (i = %3d) : %.0f | ", value, i, (double)fps_distribution[i]);
89 cum += fps_distribution[i];
90 if (*low < 0 && cum >= cum_low)
91 *low = value;
92 if (*median < 0 && cum >= cum_median)
93 *median = value;
94 if (*high < 0 && cum >= cum_high)
95 *high = value;
96 }
97 }
98