From c0547f5691c9293f82f6713d18b344524146441a Mon Sep 17 00:00:00 2001 From: marynate Date: Wed, 19 Feb 2014 23:35:39 +0800 Subject: [PATCH] Add possibility to limit frame to main loop (application/target_fps) target-fps working, and use fixed physics step before adding physics-fps in project setting Complete implementation of framelimit Conflicts: main/main.cpp --- core/bind/core_bind.cpp | 10 ++++++++++ core/bind/core_bind.h | 3 +++ core/os/os.cpp | 9 +++++++++ core/os/os.h | 5 +++++ main/main.cpp | 15 +++++++++++++-- main/main.h | 3 +-- 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 28906354abd..1b4ca8151b7 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -199,6 +199,14 @@ int _OS::get_iterations_per_second() const { } +void _OS::set_target_fps(int p_fps) { + OS::get_singleton()->set_target_fps(p_fps); +} + +float _OS::get_target_fps() const { + return OS::get_singleton()->get_target_fps(); +} + void _OS::set_low_processor_usage_mode(bool p_enabled) { OS::get_singleton()->set_low_processor_usage_mode(p_enabled); @@ -537,6 +545,8 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_iterations_per_second","iterations_per_second"),&_OS::set_iterations_per_second); ObjectTypeDB::bind_method(_MD("get_iterations_per_second"),&_OS::get_iterations_per_second); + ObjectTypeDB::bind_method(_MD("set_target_fps","target_fps"),&_OS::set_target_fps); + ObjectTypeDB::bind_method(_MD("get_target_fps"),&_OS::get_target_fps); ObjectTypeDB::bind_method(_MD("has_touchscreen_ui_hint"),&_OS::has_touchscreen_ui_hint); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 0c80fb3fc4a..3d03247c07d 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -106,6 +106,9 @@ public: void set_iterations_per_second(int p_ips); int get_iterations_per_second() const; + void set_target_fps(int p_fps); + float get_target_fps() const; + void set_low_processor_usage_mode(bool p_enabled); bool is_in_low_processor_usage_mode() const; diff --git a/core/os/os.cpp b/core/os/os.cpp index c9a5cb1af84..f678d38f56c 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -92,6 +92,14 @@ int OS::get_iterations_per_second() const { return ips; } +void OS::set_target_fps(int p_fps) { + _target_fps=p_fps>0? p_fps : 0; +} + +float OS::get_target_fps() const { + return _target_fps; +} + void OS::set_low_processor_usage_mode(bool p_enabled) { low_processor_usage_mode=p_enabled; @@ -474,6 +482,7 @@ OS::OS() { _exit_code=0; _orientation=SCREEN_LANDSCAPE; _fps=1; + _target_fps=0; _render_thread_mode=RENDER_THREAD_SAFE; Math::seed(1234567); } diff --git a/core/os/os.h b/core/os/os.h index c790b386352..b41bf6ce732 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -54,6 +54,7 @@ class OS { int _exit_code; int _orientation; float _fps; + int _target_fps; char *last_error; @@ -149,8 +150,12 @@ public: virtual void set_iterations_per_second(int p_ips); virtual int get_iterations_per_second() const; + virtual void set_target_fps(int p_fps); + virtual float get_target_fps() const; + virtual float get_frames_per_second() const { return _fps; }; + virtual void set_low_processor_usage_mode(bool p_enabled); virtual bool is_in_low_processor_usage_mode() const; diff --git a/main/main.cpp b/main/main.cpp index 7d19c2ebcf5..16cb32ed0ce 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -648,7 +648,8 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas OS::get_singleton()->set_screen_orientation(OS::SCREEN_LANDSCAPE); } - OS::get_singleton()->set_iterations_per_second(GLOBAL_DEF("display/target_fps",60)); + OS::get_singleton()->set_iterations_per_second(GLOBAL_DEF("physics/fixed_fps",60)); + OS::get_singleton()->set_target_fps(GLOBAL_DEF("application/target_fps",0)); if (!OS::get_singleton()->_verbose_stdout) //overrided OS::get_singleton()->_verbose_stdout=GLOBAL_DEF("debug/verbose_stdout",false); @@ -1210,6 +1211,7 @@ bool Main::start() { } uint64_t Main::last_ticks=0; +uint64_t Main::target_ticks=0; float Main::time_accum=0; uint32_t Main::frames=0; uint32_t Main::frame=0; @@ -1295,7 +1297,6 @@ bool Main::iteration() { } } else { VisualServer::get_singleton()->flush(); // flush visual commands - } if (AudioServer::get_singleton()) @@ -1343,6 +1344,16 @@ bool Main::iteration() { OS::get_singleton()->delay_usec( OS::get_singleton()->get_frame_delay()*1000 ); } + int taret_fps = OS::get_singleton()->get_target_fps(); + if (taret_fps>0) { + uint64_t time_step = 1000000L/taret_fps; + target_ticks += time_step; + uint64_t current_ticks = OS::get_singleton()->get_ticks_usec(); + if (current_ticksdelay_usec(target_ticks-current_ticks); + current_ticks = OS::get_singleton()->get_ticks_usec(); + target_ticks = MIN(MAX(target_ticks,current_ticks-time_step),current_ticks+time_step); + } + return exit; } diff --git a/main/main.h b/main/main.h index a2508d11b73..0aa1c991086 100644 --- a/main/main.h +++ b/main/main.h @@ -40,13 +40,12 @@ class Main { static void print_help(const char* p_binary); - static uint64_t last_ticks; + static uint64_t target_ticks; static float time_accum; static uint32_t frames; static uint32_t frame; static bool force_redraw_requested; - public: static Error setup(const char *execpath,int argc, char *argv[],bool p_second_phase=true);