diff --git a/.github/workflows/of.yml b/.github/workflows/of.yml index 661de38a49f..88768ef1357 100644 --- a/.github/workflows/of.yml +++ b/.github/workflows/of.yml @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Docker Step - run: "docker run -di --name emscripten -v $PWD:/src emscripten/emsdk:3.1.73 bash" + run: "docker run -di --name emscripten -v $PWD:/src emscripten/emsdk:3.1.74 bash" # - name: Determine Release # id: vars # shell: bash diff --git a/libs/openFrameworks/events/ofEvents.cpp b/libs/openFrameworks/events/ofEvents.cpp index 671574e9623..644edadfeed 100644 --- a/libs/openFrameworks/events/ofEvents.cpp +++ b/libs/openFrameworks/events/ofEvents.cpp @@ -48,7 +48,7 @@ double ofGetLastFrameTime() { if (window) { return window->events().getLastFrameTime(); } else { - return 0.f; + return 0.0; } } @@ -123,9 +123,10 @@ int ofGetPreviousMouseY() { } ofCoreEvents::ofCoreEvents() - : targetRate(0) + : targetRate(60.0) + , fixedRateTimeNanos(std::chrono::nanoseconds(ofGetFixedStepForFps(60.0))) , bFrameRateSet(false) - , fps(60) + , fps(60.0) , currentMouseX(0) , currentMouseY(0) , previousMouseX(0) @@ -183,6 +184,7 @@ void ofCoreEvents::enable() { void ofCoreEvents::setTimeModeSystem() { timeMode = System; + fps.setTimeMode(timeMode); } ofTimeMode ofCoreEvents::getTimeMode() const { @@ -192,11 +194,13 @@ ofTimeMode ofCoreEvents::getTimeMode() const { void ofCoreEvents::setTimeModeFixedRate(uint64_t nanosecsPerFrame) { timeMode = FixedRate; fixedRateTimeNanos = std::chrono::nanoseconds(nanosecsPerFrame); + fps.setTimeMode(timeMode); } void ofCoreEvents::setTimeModeFiltered(float alpha) { timeMode = Filtered; fps.setFilterAlpha(alpha); + fps.setTimeMode(timeMode); } //-------------------------------------- @@ -210,13 +214,18 @@ void ofCoreEvents::setFrameRate(int _targetRate) { bFrameRateSet = false; } else { bFrameRateSet = true; - targetRate = _targetRate; + targetRate = static_cast(_targetRate); // uint64_t nanosPerFrame = 1000000000.0 / (double)targetRate; // timer.setPeriodicEvent(nanosPerFrame); - timerFps.setFps(targetRate); + timerFps.setFps(_targetRate); + fps.setTargetFPS(targetRate); + if (timeMode == FixedRate) { + ofSetTimeModeFixedRate(ofGetFixedStepForFps(targetRate)); + } } + } bool ofCoreEvents::getTargetFrameRateEnabled() const { @@ -301,15 +310,8 @@ bool ofCoreEvents::notifyUpdate() { //------------------------------------------ bool ofCoreEvents::notifyDraw() { - auto attended = ofNotifyEvent(draw, voidEventArgs); - - if (bFrameRateSet) { -// timer.waitNext(); - timerFps.waitNext(); - } - if (fps.getNumFrames() == 0) { - if (bFrameRateSet) fps = ofFpsCounter(targetRate); + if (bFrameRateSet) fps = ofFpsCounter(targetRate, timeMode); } else { /*if(ofIsVerticalSyncEnabled()){ float rate = ofGetRefreshRate(); @@ -318,7 +320,12 @@ bool ofCoreEvents::notifyDraw() { lastFrameTime = intervals*1000000/rate; }*/ } + if (bFrameRateSet) { +// timer.waitNext(); + timerFps.waitNext(); + } fps.newFrame(); + auto attended = ofNotifyEvent(draw, voidEventArgs); return attended; } diff --git a/libs/openFrameworks/events/ofEvents.h b/libs/openFrameworks/events/ofEvents.h index 9091268bfc9..46425b4febc 100644 --- a/libs/openFrameworks/events/ofEvents.h +++ b/libs/openFrameworks/events/ofEvents.h @@ -406,7 +406,7 @@ class ofCoreEvents { bool notifyDragEvent(ofDragInfo info); private: - float targetRate; + float targetRate = 60.0f; bool bFrameRateSet; ofTimerFps timerFps; // ofTimer timer; @@ -420,7 +420,7 @@ class ofCoreEvents { int modifiers = 0; enum TimeMode { - System, + System = 0, FixedRate, Filtered, } timeMode diff --git a/libs/openFrameworks/utils/ofConstants.h b/libs/openFrameworks/utils/ofConstants.h index ef4408ed19b..f476c7a600d 100644 --- a/libs/openFrameworks/utils/ofConstants.h +++ b/libs/openFrameworks/utils/ofConstants.h @@ -244,8 +244,12 @@ enum ofTargetPlatform{ #else // desktop linux #define TARGET_GLFW_WINDOW #define OF_RTAUDIO - #define __LINUX_PULSE__ - #define __LINUX_ALSA__ + #ifndef __LINUX_PULSE__ + #define __LINUX_PULSE__ + #endif + #ifndef __LINUX_ALSA__ + #define __LINUX_ALSA__ + #endif #define __LINUX_OSS__ #include #endif diff --git a/libs/openFrameworks/utils/ofFpsCounter.cpp b/libs/openFrameworks/utils/ofFpsCounter.cpp index 31674c4eadf..022a8742af7 100644 --- a/libs/openFrameworks/utils/ofFpsCounter.cpp +++ b/libs/openFrameworks/utils/ofFpsCounter.cpp @@ -1,18 +1,37 @@ #include "ofFpsCounter.h" +#include using namespace std::chrono; -ofFpsCounter::ofFpsCounter() {} +ofFpsCounter::ofFpsCounter() + : lastFrameTime(std::chrono::duration(0)) + , diff(std::chrono::duration(0)) + , then(std::chrono::steady_clock::now()) + , timeMode(0) { + timestamps.clear(); + timestamps.resize(targetFPS + 7); + } -ofFpsCounter::ofFpsCounter(double targetFPS) : fps(targetFPS) {} +ofFpsCounter::ofFpsCounter(double targetFPS, int mode) + : targetFPS(targetFPS) + , lastFrameTime(std::chrono::duration(0)) + , diff(std::chrono::duration(0)) + , then(std::chrono::steady_clock::now()) + , timeMode(mode) { + timestamps.clear(); + timestamps.resize(targetFPS + 7); + } void ofFpsCounter::newFrame(){ now = steady_clock::now(); - update(now); - timestamps.push(now); + timestamps.push_back(now); lastFrameTime = now - then; - + update(now); // std::lerp from c++20 on - filteredTime = filteredTime * filterAlpha + getLastFrameSecs() * (1-filterAlpha); + if (timeMode == 2) { // Filtered + filterAlpha = std::clamp(filterAlpha, 0.0, 1.0); + filteredTime = filteredTime * filterAlpha + getLastFrameSecs() * (1.0 - filterAlpha); + filteredTime = std::clamp(filteredTime, 0.0, 1.0 / targetFPS); + } then = now; nFrameCount++; } @@ -24,18 +43,19 @@ void ofFpsCounter::update(){ void ofFpsCounter::update(time_point now){ while(!timestamps.empty() && timestamps.front() + 2s < now){ - timestamps.pop(); + timestamps.pop_front(); } - - space diff; - if(!timestamps.empty() && timestamps.front() + 0.5s < now){ - diff = now - timestamps.front(); + if (timestamps.size() < 2) { + fps = targetFPS; // if no sample size then set fps to target until can sample + return; } - if(diff > 0.0s){ - fps = (double)timestamps.size() / std::chrono::duration(diff).count(); - }else{ + diff = now - timestamps.front(); + if (diff > std::chrono::duration(0)) { + fps = static_cast(timestamps.size()) / std::chrono::duration(diff).count(); + } else { fps = timestamps.size(); } + } double ofFpsCounter::getFps() const{ @@ -51,7 +71,7 @@ uint64_t ofFpsCounter::getLastFrameNanos() const{ } double ofFpsCounter::getLastFrameSecs() const{ - return duration_cast(lastFrameTime).count(); + return std::chrono::duration(lastFrameTime).count(); } uint64_t ofFpsCounter::getLastFrameFilteredNanos() const{ @@ -59,9 +79,20 @@ uint64_t ofFpsCounter::getLastFrameFilteredNanos() const{ } double ofFpsCounter::getLastFrameFilteredSecs() const{ - return filteredTime; + return std::chrono::duration(filteredTime).count(); } void ofFpsCounter::setFilterAlpha(float alpha){ filterAlpha = alpha; } + +void ofFpsCounter::setTimeMode(int mode) { + timeMode = mode; +} + +void ofFpsCounter::setTargetFPS(double fps) { + targetFPS = fps; + if (fps > timestamps.max_size()) { + timestamps.resize(fps); + } +} diff --git a/libs/openFrameworks/utils/ofFpsCounter.h b/libs/openFrameworks/utils/ofFpsCounter.h index 3e2fb22a13a..4b8158dc030 100644 --- a/libs/openFrameworks/utils/ofFpsCounter.h +++ b/libs/openFrameworks/utils/ofFpsCounter.h @@ -1,12 +1,12 @@ #pragma once -#include +#include #include class ofFpsCounter { public: ofFpsCounter(); - ofFpsCounter(double targetFps); + ofFpsCounter(double targetFps, int mode = 0); void newFrame(); // no need to call it usually, useful if @@ -22,17 +22,22 @@ class ofFpsCounter { uint64_t getLastFrameFilteredNanos() const; double getLastFrameFilteredSecs() const; void setFilterAlpha(float alpha); + void setTimeMode(int mode); + void setTargetFPS(double fps); private: void update(std::chrono::time_point now); uint64_t nFrameCount = 0; - double fps = 0; + double fps = 0.0; + double targetFPS = 60.0; using space = std::chrono::duration; std::chrono::time_point now = std::chrono::steady_clock::now(); std::chrono::time_point then = std::chrono::steady_clock::now(); space lastFrameTime; - double filteredTime = 0; + space diff; + double filteredTime = 0.0; double filterAlpha = 0.9; - std::queue> timestamps; + std::deque> timestamps; + int timeMode = 0; }; diff --git a/libs/openFrameworks/utils/ofTimerFps.cpp b/libs/openFrameworks/utils/ofTimerFps.cpp index 7083088af25..03a4d85d697 100644 --- a/libs/openFrameworks/utils/ofTimerFps.cpp +++ b/libs/openFrameworks/utils/ofTimerFps.cpp @@ -7,13 +7,19 @@ void ofTimerFps::reset() { wakeTime = steady_clock::now(); } -ofTimerFps::ofTimerFps(){ +ofTimerFps::ofTimerFps() { reset(); + interval = duration_cast(1s) / currentFPS; }; void ofTimerFps::setFps(int fps) { // interval = std::ratio<1s, fps>; - interval = duration_cast(1s) / fps; + if (fps <= 0) { + fps = 60; // fallback + } + currentFPS = fps; + + interval = duration_cast(1s) / currentFPS; } void ofTimerFps::waitNext() { diff --git a/libs/openFrameworks/utils/ofTimerFps.h b/libs/openFrameworks/utils/ofTimerFps.h index e0fed4baf94..de2ccbf65f0 100644 --- a/libs/openFrameworks/utils/ofTimerFps.h +++ b/libs/openFrameworks/utils/ofTimerFps.h @@ -18,5 +18,6 @@ class ofTimerFps { space interval; std::chrono::time_point wakeTime; std::chrono::time_point lastWakeTime; + int currentFPS = 60; }; diff --git a/scripts/ci/emscripten/build.sh b/scripts/ci/emscripten/build.sh index 91a915e7cc5..420311a7c46 100755 --- a/scripts/ci/emscripten/build.sh +++ b/scripts/ci/emscripten/build.sh @@ -14,34 +14,10 @@ cd $ROOT #echo "PLATFORM_CFLAGS += $CUSTOMFLAGS" >> libs/openFrameworksCompiled/project/emscripten/config.emscripten.default.mk sed -i "s/PLATFORM_OPTIMIZATION_CFLAGS_DEBUG = .*/PLATFORM_OPTIMIZATION_CFLAGS_DEBUG = -g0/" libs/openFrameworksCompiled/project/emscripten/config.emscripten.default.mk cd libs/openFrameworksCompiled/project -emmake make -j Debug +EMCC_DEBUG=1 emmake make -j Debug echo "**** Building emptyExample ****" cd $ROOT/scripts/templates/linux64 -emmake make -j Debug +EMCC_DEBUG=1 emmake make -j Debug -echo "**** Building allAddonsExample ****" -cd $ROOT -cp scripts/templates/linux64/Makefile examples/templates/allAddonsExample/ -cp scripts/templates/linux64/config.make examples/templates/allAddonsExample/ -cd examples/templates/allAddonsExample/ -sed -i s/ofxOsc// addons.make -sed -i s/ofxNetwork// addons.make -sed -i s/ofxKinect// addons.make -sed -i s/ofxThreadedImageLoader// addons.make -sed -i s/ofxPoco// addons.make - -sed -i "s/#include \"ofxOsc.h\"//" src/ofApp.h -sed -i "s/#include \"ofxNetwork.h\"//" src/ofApp.h -sed -i "s/#include \"ofxKinect.h\"//" src/ofApp.h -sed -i "s/#include \"ofxThreadedImageLoader.h\"//" src/ofApp.h -sed -i "s/#include \"ofxXmlPoco.h\"//" src/ofApp.h - -sed -i "s/ofxTCPClient client;//" src/ofApp.h -sed -i "s/ofxTCPServer server;//" src/ofApp.h -sed -i "s/ofxOscSender osc_sender;//" src/ofApp.h -sed -i "s/ofxKinect kinect;//" src/ofApp.h -sed -i "s/ofxThreadedImageLoader .*;//" src/ofApp.h -sed -i "s/ofxXmlPoco .*;//" src/ofApp.h - -emmake make -j Debug +echo "**** Building default template complete ****" diff --git a/scripts/ci/emscripten/build_addons.sh b/scripts/ci/emscripten/build_addons.sh new file mode 100644 index 00000000000..9495350909d --- /dev/null +++ b/scripts/ci/emscripten/build_addons.sh @@ -0,0 +1,37 @@ +#!/bin/bash +set -ev +ROOT=${TRAVIS_BUILD_DIR:-"$( cd "$(dirname "$0")/../../.." ; pwd -P )"} + +echo "**** Building OF core ****" +cd $ROOT +# this carries over to subsequent compilations of examples +#echo "PLATFORM_CFLAGS += $CUSTOMFLAGS" >> libs/openFrameworksCompiled/project/emscripten/config.emscripten.default.mk +sed -i "s/PLATFORM_OPTIMIZATION_CFLAGS_DEBUG = .*/PLATFORM_OPTIMIZATION_CFLAGS_DEBUG = -g0/" libs/openFrameworksCompiled/project/emscripten/config.emscripten.default.mk +cd libs/openFrameworksCompiled/project +EMCC_DEBUG=1 emmake make -j Debug + +echo "**** Building allAddonsExample ****" +cd $ROOT +cp scripts/templates/linux64/Makefile examples/templates/allAddonsExample/ +cp scripts/templates/linux64/config.make examples/templates/allAddonsExample/ +cd examples/templates/allAddonsExample/ +sed -i s/ofxOsc// addons.make +sed -i s/ofxNetwork// addons.make +sed -i s/ofxKinect// addons.make +sed -i s/ofxThreadedImageLoader// addons.make +sed -i s/ofxPoco// addons.make + +sed -i "s/#include \"ofxOsc.h\"//" src/ofApp.h +sed -i "s/#include \"ofxNetwork.h\"//" src/ofApp.h +sed -i "s/#include \"ofxKinect.h\"//" src/ofApp.h +sed -i "s/#include \"ofxThreadedImageLoader.h\"//" src/ofApp.h +sed -i "s/#include \"ofxXmlPoco.h\"//" src/ofApp.h + +sed -i "s/ofxTCPClient client;//" src/ofApp.h +sed -i "s/ofxTCPServer server;//" src/ofApp.h +sed -i "s/ofxOscSender osc_sender;//" src/ofApp.h +sed -i "s/ofxKinect kinect;//" src/ofApp.h +sed -i "s/ofxThreadedImageLoader .*;//" src/ofApp.h +sed -i "s/ofxXmlPoco .*;//" src/ofApp.h + +EMCC_DEBUG=1 emmake make -j Debug diff --git a/scripts/ci/linux64/run_tests.sh b/scripts/ci/linux64/run_tests.sh index f1c5bc5b07b..2f247e16e1e 100755 --- a/scripts/ci/linux64/run_tests.sh +++ b/scripts/ci/linux64/run_tests.sh @@ -16,13 +16,22 @@ for group in *; do cd $test cp ../../../scripts/templates/linux/Makefile . cp ../../../scripts/templates/linux/config.make . + sleep 0.3 make -j2 Debug + sleep 0.3 cd bin binname=$(basename ${test}) - #gdb -batch -ex "run" -ex "bt" -ex "q \$_exitcode" ./${binname}_debug - ./${binname}_debug + + if [[ -f ./${binname}_debug ]]; then + gdb -batch -ex "run" -ex "bt" -ex "q \$_exitcode" ./${binname}_debug + #./${binname}_debug + else + echo "Binary not found: ${binname}_debug" + exit 1 + fi errorcode=$? if [[ $errorcode -ne 0 ]]; then + echo "Test failed: ${binname}_debug with error code: $errorcode" exit $errorcode fi cd $ROOT/tests