Browse Source

Merge pull request #212 from marynate/PR-framelimit

Add ability to apply frame rate limit (application/target_fps)
reduz 11 years ago
parent
commit
f9820d4c40
6 changed files with 41 additions and 4 deletions
  1. 10 0
      core/bind/core_bind.cpp
  2. 3 0
      core/bind/core_bind.h
  3. 9 0
      core/os/os.cpp
  4. 5 0
      core/os/os.h
  5. 13 2
      main/main.cpp
  6. 1 2
      main/main.h

+ 10 - 0
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);
 

+ 3 - 0
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;
 

+ 9 - 0
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);
 }

+ 5 - 0
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;
 

+ 13 - 2
main/main.cpp

@@ -651,7 +651,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);
@@ -1213,6 +1214,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;
@@ -1298,7 +1300,6 @@ bool Main::iteration() {
 		}
 	} else {
 		VisualServer::get_singleton()->flush(); // flush visual commands
-
 	}
 
 	if (AudioServer::get_singleton())
@@ -1346,6 +1347,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_ticks<target_ticks) OS::get_singleton()->delay_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;
 }
 

+ 1 - 2
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);