1 #include "core/framerate.hpp"
2 #include "core/settings.hpp"
12 #define DEFAULT_NOMINAL_RATE 60
16 double nominal_rate
= DEFAULT_NOMINAL_RATE
;
18 const double exp_factor
= 0.97;
19 uint64_t last_frame_usec
= 0;
20 bool last_frame_usec_valid
= false;
21 bool target_nominal
= true;
22 double target_fps
= DEFAULT_NOMINAL_RATE
;
23 bool target_infinite
= false;
24 uint64_t wait_duration
= 0;
26 struct setting_targetfps
: public setting
28 setting_targetfps() throw(std::bad_alloc
)
29 : setting("targetfps")
33 void blank() throw(std::bad_alloc
, std::runtime_error
)
35 target_nominal
= true;
36 target_infinite
= false;
37 target_fps
= nominal_rate
;
42 return !target_nominal
;
45 virtual void set(const std::string
& value
) throw(std::bad_alloc
, std::runtime_error
)
50 if(value
== "infinite") {
51 target_infinite
= true;
52 target_nominal
= false;
58 throw std::runtime_error("Invalid frame rate");
60 throw std::runtime_error("Target frame rate must be at least 0.001fps");
62 target_infinite
= false;
63 target_nominal
= false;
66 virtual std::string
get() throw(std::bad_alloc
)
80 void set_nominal_framerate(double fps
) throw()
84 target_fps
= nominal_rate
;
85 target_infinite
= false;
89 double get_framerate() throw()
94 void ack_frame_tick(uint64_t usec
) throw()
96 if(!last_frame_usec_valid
) {
97 last_frame_usec
= usec
;
98 last_frame_usec_valid
= true;
101 uint64_t frame_usec
= usec
- last_frame_usec
;
102 fps_value
= exp_factor
* fps_value
+ (1 - exp_factor
) * (1000000.0 / frame_usec
);
103 last_frame_usec
= usec
;
106 uint64_t to_wait_frame(uint64_t usec
) throw()
108 //Very simple algorithm. TODO: Make better one.
109 if(!last_frame_usec_valid
|| target_infinite
)
111 if(get_framerate() < target_fps
&& wait_duration
> 0)
112 wait_duration
-= 1000;
113 else if(get_framerate() > target_fps
)
114 wait_duration
+= 1000;
115 return wait_duration
;
122 gettimeofday(&tv
, NULL
);
123 return static_cast<uint64_t>(tv
.tv_sec
) * 1000000 + tv
.tv_usec
;
126 #define MAXSLEEP 500000
128 void wait_usec(uint64_t usec
)
130 uint64_t sleep_end
= get_utime() + usec
;
132 uint64_t time_now
= get_utime();
133 if(time_now
>= sleep_end
)
135 if(sleep_end
< time_now
+ MAXSLEEP
)
136 usleep(sleep_end
- time_now
);