Skip to content

Commit a34ab60

Browse files
authored
Fix: ofGetLastFrameTime() always returns 0 (Filtered/System timeMode) Bug (#8240)
* timer debugging * Timer Fixes * Fixed defaults. * Emscripten 3.1.74. Spit CI to default and addons for more clarity of issues * Linux defines fix * Fix for divide by zero * Fix double longs * double double * linux double issues * linux debug * timer what * targetRate type fixes * ofTimerFPS fix for default ctor list * bash fixes
1 parent ba02087 commit a34ab60

File tree

11 files changed

+146
-70
lines changed

11 files changed

+146
-70
lines changed

.github/workflows/of.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
steps:
3333
- uses: actions/checkout@v4
3434
- name: Docker Step
35-
run: "docker run -di --name emscripten -v $PWD:/src emscripten/emsdk:3.1.73 bash"
35+
run: "docker run -di --name emscripten -v $PWD:/src emscripten/emsdk:3.1.74 bash"
3636
# - name: Determine Release
3737
# id: vars
3838
# shell: bash

libs/openFrameworks/events/ofEvents.cpp

+20-13
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ double ofGetLastFrameTime() {
4848
if (window) {
4949
return window->events().getLastFrameTime();
5050
} else {
51-
return 0.f;
51+
return 0.0;
5252
}
5353
}
5454

@@ -123,9 +123,10 @@ int ofGetPreviousMouseY() {
123123
}
124124

125125
ofCoreEvents::ofCoreEvents()
126-
: targetRate(0)
126+
: targetRate(60.0)
127+
, fixedRateTimeNanos(std::chrono::nanoseconds(ofGetFixedStepForFps(60.0)))
127128
, bFrameRateSet(false)
128-
, fps(60)
129+
, fps(60.0)
129130
, currentMouseX(0)
130131
, currentMouseY(0)
131132
, previousMouseX(0)
@@ -183,6 +184,7 @@ void ofCoreEvents::enable() {
183184

184185
void ofCoreEvents::setTimeModeSystem() {
185186
timeMode = System;
187+
fps.setTimeMode(timeMode);
186188
}
187189

188190
ofTimeMode ofCoreEvents::getTimeMode() const {
@@ -192,11 +194,13 @@ ofTimeMode ofCoreEvents::getTimeMode() const {
192194
void ofCoreEvents::setTimeModeFixedRate(uint64_t nanosecsPerFrame) {
193195
timeMode = FixedRate;
194196
fixedRateTimeNanos = std::chrono::nanoseconds(nanosecsPerFrame);
197+
fps.setTimeMode(timeMode);
195198
}
196199

197200
void ofCoreEvents::setTimeModeFiltered(float alpha) {
198201
timeMode = Filtered;
199202
fps.setFilterAlpha(alpha);
203+
fps.setTimeMode(timeMode);
200204
}
201205

202206
//--------------------------------------
@@ -210,13 +214,18 @@ void ofCoreEvents::setFrameRate(int _targetRate) {
210214
bFrameRateSet = false;
211215
} else {
212216
bFrameRateSet = true;
213-
targetRate = _targetRate;
217+
targetRate = static_cast<float>(_targetRate);
214218

215219
// uint64_t nanosPerFrame = 1000000000.0 / (double)targetRate;
216220
// timer.setPeriodicEvent(nanosPerFrame);
217221

218-
timerFps.setFps(targetRate);
222+
timerFps.setFps(_targetRate);
223+
fps.setTargetFPS(targetRate);
224+
if (timeMode == FixedRate) {
225+
ofSetTimeModeFixedRate(ofGetFixedStepForFps(targetRate));
226+
}
219227
}
228+
220229
}
221230

222231
bool ofCoreEvents::getTargetFrameRateEnabled() const {
@@ -301,15 +310,8 @@ bool ofCoreEvents::notifyUpdate() {
301310

302311
//------------------------------------------
303312
bool ofCoreEvents::notifyDraw() {
304-
auto attended = ofNotifyEvent(draw, voidEventArgs);
305-
306-
if (bFrameRateSet) {
307-
// timer.waitNext();
308-
timerFps.waitNext();
309-
}
310-
311313
if (fps.getNumFrames() == 0) {
312-
if (bFrameRateSet) fps = ofFpsCounter(targetRate);
314+
if (bFrameRateSet) fps = ofFpsCounter(targetRate, timeMode);
313315
} else {
314316
/*if(ofIsVerticalSyncEnabled()){
315317
float rate = ofGetRefreshRate();
@@ -318,7 +320,12 @@ bool ofCoreEvents::notifyDraw() {
318320
lastFrameTime = intervals*1000000/rate;
319321
}*/
320322
}
323+
if (bFrameRateSet) {
324+
// timer.waitNext();
325+
timerFps.waitNext();
326+
}
321327
fps.newFrame();
328+
auto attended = ofNotifyEvent(draw, voidEventArgs);
322329
return attended;
323330
}
324331

libs/openFrameworks/events/ofEvents.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ class ofCoreEvents {
406406
bool notifyDragEvent(ofDragInfo info);
407407

408408
private:
409-
float targetRate;
409+
float targetRate = 60.0f;
410410
bool bFrameRateSet;
411411
ofTimerFps timerFps;
412412
// ofTimer timer;
@@ -420,7 +420,7 @@ class ofCoreEvents {
420420
int modifiers = 0;
421421

422422
enum TimeMode {
423-
System,
423+
System = 0,
424424
FixedRate,
425425
Filtered,
426426
} timeMode

libs/openFrameworks/utils/ofConstants.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,12 @@ enum ofTargetPlatform{
244244
#else // desktop linux
245245
#define TARGET_GLFW_WINDOW
246246
#define OF_RTAUDIO
247-
#define __LINUX_PULSE__
248-
#define __LINUX_ALSA__
247+
#ifndef __LINUX_PULSE__
248+
#define __LINUX_PULSE__
249+
#endif
250+
#ifndef __LINUX_ALSA__
251+
#define __LINUX_ALSA__
252+
#endif
249253
#define __LINUX_OSS__
250254
#include <GL/glew.h>
251255
#endif
+47-16
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,37 @@
11
#include "ofFpsCounter.h"
2+
#include <ofUtils.h>
23
using namespace std::chrono;
34

4-
ofFpsCounter::ofFpsCounter() {}
5+
ofFpsCounter::ofFpsCounter()
6+
: lastFrameTime(std::chrono::duration<long long, std::nano>(0))
7+
, diff(std::chrono::duration<long long, std::nano>(0))
8+
, then(std::chrono::steady_clock::now())
9+
, timeMode(0) {
10+
timestamps.clear();
11+
timestamps.resize(targetFPS + 7);
12+
}
513

6-
ofFpsCounter::ofFpsCounter(double targetFPS) : fps(targetFPS) {}
14+
ofFpsCounter::ofFpsCounter(double targetFPS, int mode)
15+
: targetFPS(targetFPS)
16+
, lastFrameTime(std::chrono::duration<long long, std::nano>(0))
17+
, diff(std::chrono::duration<long long, std::nano>(0))
18+
, then(std::chrono::steady_clock::now())
19+
, timeMode(mode) {
20+
timestamps.clear();
21+
timestamps.resize(targetFPS + 7);
22+
}
723

824
void ofFpsCounter::newFrame(){
925
now = steady_clock::now();
10-
update(now);
11-
timestamps.push(now);
26+
timestamps.push_back(now);
1227
lastFrameTime = now - then;
13-
28+
update(now);
1429
// std::lerp from c++20 on
15-
filteredTime = filteredTime * filterAlpha + getLastFrameSecs() * (1-filterAlpha);
30+
if (timeMode == 2) { // Filtered
31+
filterAlpha = std::clamp(filterAlpha, 0.0, 1.0);
32+
filteredTime = filteredTime * filterAlpha + getLastFrameSecs() * (1.0 - filterAlpha);
33+
filteredTime = std::clamp(filteredTime, 0.0, 1.0 / targetFPS);
34+
}
1635
then = now;
1736
nFrameCount++;
1837
}
@@ -24,18 +43,19 @@ void ofFpsCounter::update(){
2443

2544
void ofFpsCounter::update(time_point<steady_clock> now){
2645
while(!timestamps.empty() && timestamps.front() + 2s < now){
27-
timestamps.pop();
46+
timestamps.pop_front();
2847
}
29-
30-
space diff;
31-
if(!timestamps.empty() && timestamps.front() + 0.5s < now){
32-
diff = now - timestamps.front();
48+
if (timestamps.size() < 2) {
49+
fps = targetFPS; // if no sample size then set fps to target until can sample
50+
return;
3351
}
34-
if(diff > 0.0s){
35-
fps = (double)timestamps.size() / std::chrono::duration<double>(diff).count();
36-
}else{
52+
diff = now - timestamps.front();
53+
if (diff > std::chrono::duration<double>(0)) {
54+
fps = static_cast<double>(timestamps.size()) / std::chrono::duration<double>(diff).count();
55+
} else {
3756
fps = timestamps.size();
3857
}
58+
3959
}
4060

4161
double ofFpsCounter::getFps() const{
@@ -51,17 +71,28 @@ uint64_t ofFpsCounter::getLastFrameNanos() const{
5171
}
5272

5373
double ofFpsCounter::getLastFrameSecs() const{
54-
return duration_cast<seconds>(lastFrameTime).count();
74+
return std::chrono::duration<double>(lastFrameTime).count();
5575
}
5676

5777
uint64_t ofFpsCounter::getLastFrameFilteredNanos() const{
5878
return duration_cast<nanoseconds>(lastFrameTime).count();
5979
}
6080

6181
double ofFpsCounter::getLastFrameFilteredSecs() const{
62-
return filteredTime;
82+
return std::chrono::duration<double>(filteredTime).count();
6383
}
6484

6585
void ofFpsCounter::setFilterAlpha(float alpha){
6686
filterAlpha = alpha;
6787
}
88+
89+
void ofFpsCounter::setTimeMode(int mode) {
90+
timeMode = mode;
91+
}
92+
93+
void ofFpsCounter::setTargetFPS(double fps) {
94+
targetFPS = fps;
95+
if (fps > timestamps.max_size()) {
96+
timestamps.resize(fps);
97+
}
98+
}

libs/openFrameworks/utils/ofFpsCounter.h

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#pragma once
22

3-
#include <queue>
3+
#include <deque>
44
#include <chrono>
55

66
class ofFpsCounter {
77
public:
88
ofFpsCounter();
9-
ofFpsCounter(double targetFps);
9+
ofFpsCounter(double targetFps, int mode = 0);
1010
void newFrame();
1111

1212
// no need to call it usually, useful if
@@ -22,17 +22,22 @@ class ofFpsCounter {
2222
uint64_t getLastFrameFilteredNanos() const;
2323
double getLastFrameFilteredSecs() const;
2424
void setFilterAlpha(float alpha);
25+
void setTimeMode(int mode);
26+
void setTargetFPS(double fps);
2527

2628
private:
2729
void update(std::chrono::time_point<std::chrono::steady_clock> now);
2830
uint64_t nFrameCount = 0;
29-
double fps = 0;
31+
double fps = 0.0;
32+
double targetFPS = 60.0;
3033

3134
using space = std::chrono::duration<long long, std::nano>;
3235
std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
3336
std::chrono::time_point<std::chrono::steady_clock> then = std::chrono::steady_clock::now();
3437
space lastFrameTime;
35-
double filteredTime = 0;
38+
space diff;
39+
double filteredTime = 0.0;
3640
double filterAlpha = 0.9;
37-
std::queue<std::chrono::time_point<std::chrono::steady_clock>> timestamps;
41+
std::deque<std::chrono::time_point<std::chrono::steady_clock>> timestamps;
42+
int timeMode = 0;
3843
};

libs/openFrameworks/utils/ofTimerFps.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@ void ofTimerFps::reset() {
77
wakeTime = steady_clock::now();
88
}
99

10-
ofTimerFps::ofTimerFps(){
10+
ofTimerFps::ofTimerFps() {
1111
reset();
12+
interval = duration_cast<microseconds>(1s) / currentFPS;
1213
};
1314

1415
void ofTimerFps::setFps(int fps) {
1516
// interval = std::ratio<1s, fps>;
16-
interval = duration_cast<microseconds>(1s) / fps;
17+
if (fps <= 0) {
18+
fps = 60; // fallback
19+
}
20+
currentFPS = fps;
21+
22+
interval = duration_cast<microseconds>(1s) / currentFPS;
1723
}
1824

1925
void ofTimerFps::waitNext() {

libs/openFrameworks/utils/ofTimerFps.h

+1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ class ofTimerFps {
1818
space interval;
1919
std::chrono::time_point<std::chrono::steady_clock> wakeTime;
2020
std::chrono::time_point<std::chrono::steady_clock> lastWakeTime;
21+
int currentFPS = 60;
2122

2223
};

scripts/ci/emscripten/build.sh

+3-27
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,10 @@ cd $ROOT
1414
#echo "PLATFORM_CFLAGS += $CUSTOMFLAGS" >> libs/openFrameworksCompiled/project/emscripten/config.emscripten.default.mk
1515
sed -i "s/PLATFORM_OPTIMIZATION_CFLAGS_DEBUG = .*/PLATFORM_OPTIMIZATION_CFLAGS_DEBUG = -g0/" libs/openFrameworksCompiled/project/emscripten/config.emscripten.default.mk
1616
cd libs/openFrameworksCompiled/project
17-
emmake make -j Debug
17+
EMCC_DEBUG=1 emmake make -j Debug
1818

1919
echo "**** Building emptyExample ****"
2020
cd $ROOT/scripts/templates/linux64
21-
emmake make -j Debug
21+
EMCC_DEBUG=1 emmake make -j Debug
2222

23-
echo "**** Building allAddonsExample ****"
24-
cd $ROOT
25-
cp scripts/templates/linux64/Makefile examples/templates/allAddonsExample/
26-
cp scripts/templates/linux64/config.make examples/templates/allAddonsExample/
27-
cd examples/templates/allAddonsExample/
28-
sed -i s/ofxOsc// addons.make
29-
sed -i s/ofxNetwork// addons.make
30-
sed -i s/ofxKinect// addons.make
31-
sed -i s/ofxThreadedImageLoader// addons.make
32-
sed -i s/ofxPoco// addons.make
33-
34-
sed -i "s/#include \"ofxOsc.h\"//" src/ofApp.h
35-
sed -i "s/#include \"ofxNetwork.h\"//" src/ofApp.h
36-
sed -i "s/#include \"ofxKinect.h\"//" src/ofApp.h
37-
sed -i "s/#include \"ofxThreadedImageLoader.h\"//" src/ofApp.h
38-
sed -i "s/#include \"ofxXmlPoco.h\"//" src/ofApp.h
39-
40-
sed -i "s/ofxTCPClient client;//" src/ofApp.h
41-
sed -i "s/ofxTCPServer server;//" src/ofApp.h
42-
sed -i "s/ofxOscSender osc_sender;//" src/ofApp.h
43-
sed -i "s/ofxKinect kinect;//" src/ofApp.h
44-
sed -i "s/ofxThreadedImageLoader .*;//" src/ofApp.h
45-
sed -i "s/ofxXmlPoco .*;//" src/ofApp.h
46-
47-
emmake make -j Debug
23+
echo "**** Building default template complete ****"

scripts/ci/emscripten/build_addons.sh

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
set -ev
3+
ROOT=${TRAVIS_BUILD_DIR:-"$( cd "$(dirname "$0")/../../.." ; pwd -P )"}
4+
5+
echo "**** Building OF core ****"
6+
cd $ROOT
7+
# this carries over to subsequent compilations of examples
8+
#echo "PLATFORM_CFLAGS += $CUSTOMFLAGS" >> libs/openFrameworksCompiled/project/emscripten/config.emscripten.default.mk
9+
sed -i "s/PLATFORM_OPTIMIZATION_CFLAGS_DEBUG = .*/PLATFORM_OPTIMIZATION_CFLAGS_DEBUG = -g0/" libs/openFrameworksCompiled/project/emscripten/config.emscripten.default.mk
10+
cd libs/openFrameworksCompiled/project
11+
EMCC_DEBUG=1 emmake make -j Debug
12+
13+
echo "**** Building allAddonsExample ****"
14+
cd $ROOT
15+
cp scripts/templates/linux64/Makefile examples/templates/allAddonsExample/
16+
cp scripts/templates/linux64/config.make examples/templates/allAddonsExample/
17+
cd examples/templates/allAddonsExample/
18+
sed -i s/ofxOsc// addons.make
19+
sed -i s/ofxNetwork// addons.make
20+
sed -i s/ofxKinect// addons.make
21+
sed -i s/ofxThreadedImageLoader// addons.make
22+
sed -i s/ofxPoco// addons.make
23+
24+
sed -i "s/#include \"ofxOsc.h\"//" src/ofApp.h
25+
sed -i "s/#include \"ofxNetwork.h\"//" src/ofApp.h
26+
sed -i "s/#include \"ofxKinect.h\"//" src/ofApp.h
27+
sed -i "s/#include \"ofxThreadedImageLoader.h\"//" src/ofApp.h
28+
sed -i "s/#include \"ofxXmlPoco.h\"//" src/ofApp.h
29+
30+
sed -i "s/ofxTCPClient client;//" src/ofApp.h
31+
sed -i "s/ofxTCPServer server;//" src/ofApp.h
32+
sed -i "s/ofxOscSender osc_sender;//" src/ofApp.h
33+
sed -i "s/ofxKinect kinect;//" src/ofApp.h
34+
sed -i "s/ofxThreadedImageLoader .*;//" src/ofApp.h
35+
sed -i "s/ofxXmlPoco .*;//" src/ofApp.h
36+
37+
EMCC_DEBUG=1 emmake make -j Debug

0 commit comments

Comments
 (0)