Ver Fonte

Made sim & core thread run in lockstep

Marko Pintera há 12 anos atrás
pai
commit
cc20378a61
3 ficheiros alterados com 18 adições e 19 exclusões
  1. 1 0
      CamelotCore/Include/CmApplication.h
  2. 14 19
      CamelotCore/Source/CmApplication.cpp
  3. 3 0
      TODO.txt

+ 1 - 0
CamelotCore/Include/CmApplication.h

@@ -87,6 +87,7 @@ namespace CamelotFramework
 
 
 		bool mIsFrameRenderingFinished;
 		bool mIsFrameRenderingFinished;
 		CM_MUTEX(mFrameRenderingFinishedMutex);
 		CM_MUTEX(mFrameRenderingFinishedMutex);
+		CM_THREAD_SYNCHRONISER(mFrameRenderingFinishedCondition);
 
 
 		volatile bool mRunMainLoop;
 		volatile bool mRunMainLoop;
 
 

+ 14 - 19
CamelotCore/Source/CmApplication.cpp

@@ -99,28 +99,22 @@ namespace CamelotFramework
 
 
 			RendererManager::instance().getActive()->renderAll();
 			RendererManager::instance().getActive()->renderAll();
 
 
-			// Only queue new commands if core thread has finished rendering
-			// TODO - There might be a more optimal way to sync simulation and core threads so we maximize
-			// the amount of rendered frames
-			bool readyForNextFrame = false;
+			// Core and sim thread run in lockstep. This will result in a larger input latency than if I was 
+			// running just a single thread. Latency becomes worse if the core thread takes longer than sim 
+			// thread, in which case sim thread needs to wait. Optimal solution would be to get an average 
+			// difference between sim/core thread and start the sim thread a bit later so they finish at nearly the same time.
 			{
 			{
-				CM_LOCK_MUTEX(mFrameRenderingFinishedMutex);
-				readyForNextFrame = mIsFrameRenderingFinished;
-			}
+				CM_LOCK_MUTEX_NAMED(mFrameRenderingFinishedMutex, lock);
 
 
-			if(readyForNextFrame)
-			{
-				{
-					CM_LOCK_MUTEX(mFrameRenderingFinishedMutex);
-					mIsFrameRenderingFinished = false;
-				}
-				
-				gCoreThread().queueCommand(boost::bind(&Application::updateMessagePump, this));
-				mPrimaryCoreAccessor->submitToCoreThread();
-				gCoreThread().queueCommand(boost::bind(&Application::frameRenderingFinishedCallback, this));
+				while(!mIsFrameRenderingFinished)
+					CM_THREAD_WAIT(mFrameRenderingFinishedCondition, mFrameRenderingFinishedMutex, lock);
+
+				mIsFrameRenderingFinished = false;
 			}
 			}
-			else
-				mPrimaryCoreAccessor->cancelAll();
+
+			gCoreThread().queueCommand(boost::bind(&Application::updateMessagePump, this));
+			mPrimaryCoreAccessor->submitToCoreThread();
+			gCoreThread().queueCommand(boost::bind(&Application::frameRenderingFinishedCallback, this));
 
 
 			gTime().update();
 			gTime().update();
 		}
 		}
@@ -142,6 +136,7 @@ namespace CamelotFramework
 		CM_LOCK_MUTEX(mFrameRenderingFinishedMutex);
 		CM_LOCK_MUTEX(mFrameRenderingFinishedMutex);
 
 
 		mIsFrameRenderingFinished = true;
 		mIsFrameRenderingFinished = true;
+		CM_THREAD_NOTIFY_ONE(mFrameRenderingFinishedCondition);
 	}
 	}
 
 
 	void Application::shutDown()
 	void Application::shutDown()

+ 3 - 0
TODO.txt

@@ -25,6 +25,9 @@ IMMEDIATE:
  - It's possible to resize smaller than 0 and cause an exception
  - It's possible to resize smaller than 0 and cause an exception
  - Cursor doesn't stay inside the window we're resizing, window seems to resize slower than the cursor moves
  - Cursor doesn't stay inside the window we're resizing, window seems to resize slower than the cursor moves
  - OpenGL resize doesn't work - I believe its because its render thread works too slow and we call "cancelAll" on the command queue. Check out why is the render thread slow, and get rid of cancelAll(), it's not a valid approach
  - OpenGL resize doesn't work - I believe its because its render thread works too slow and we call "cancelAll" on the command queue. Check out why is the render thread slow, and get rid of cancelAll(), it's not a valid approach
+  - Add special flag for commands that can or can't be dropped so I can still use "cancelAll"
+  - But just getting rid of "cancelAll" altogether is probably a better solution to get better performance, at the lost of some input lag
+    - Core and main threads should run in lockstep
  - Update debug camera so it uses callbacks
  - Update debug camera so it uses callbacks
  - Add support for diacritical marks
  - Add support for diacritical marks
  - onMovedOrResized is still used by Viewport
  - onMovedOrResized is still used by Viewport