|
|
@@ -7,7 +7,7 @@
|
|
|
namespace CamelotEngine
|
|
|
{
|
|
|
RenderSystemContext::RenderSystemContext(CM_THREAD_ID_TYPE threadId)
|
|
|
- :mMyThreadId(threadId), mReadyCommands(nullptr), mIsExecuting(false)
|
|
|
+ :mMyThreadId(threadId), mIsExecuting(false)
|
|
|
, waitForVerticalBlank(true)
|
|
|
, cullingMode(CULL_CLOCKWISE)
|
|
|
, vertexProgramBound(false)
|
|
|
@@ -18,7 +18,16 @@ namespace CamelotEngine
|
|
|
mCommands = new vector<RenderSystemCommand>::type();
|
|
|
}
|
|
|
|
|
|
- AsyncOp RenderSystemContext::queueReturnCommand(boost::function<void(AsyncOp&)> commandCallback, UINT32 _callbackId)
|
|
|
+ /************************************************************************/
|
|
|
+ /* FRAME CONTEXT */
|
|
|
+ /************************************************************************/
|
|
|
+
|
|
|
+ RenderSystemFrameContext::RenderSystemFrameContext(CM_THREAD_ID_TYPE threadId)
|
|
|
+ :RenderSystemContext(threadId), mReadyCommands(nullptr)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ AsyncOp RenderSystemFrameContext::queueReturnCommand(boost::function<void(AsyncOp&)> commandCallback, UINT32 _callbackId)
|
|
|
{
|
|
|
#if CM_DEBUG_MODE
|
|
|
#if CM_THREAD_SUPPORT != 0
|
|
|
@@ -35,7 +44,7 @@ namespace CamelotEngine
|
|
|
return newCommand.asyncOp;
|
|
|
}
|
|
|
|
|
|
- void RenderSystemContext::queueCommand(boost::function<void()> commandCallback, UINT32 _callbackId)
|
|
|
+ void RenderSystemFrameContext::queueCommand(boost::function<void()> commandCallback, UINT32 _callbackId)
|
|
|
{
|
|
|
#if CM_DEBUG_MODE
|
|
|
#if CM_THREAD_SUPPORT != 0
|
|
|
@@ -50,7 +59,7 @@ namespace CamelotEngine
|
|
|
mCommands->push_back(newCommand);
|
|
|
}
|
|
|
|
|
|
- void RenderSystemContext::submitToGpu()
|
|
|
+ void RenderSystemFrameContext::submitToGpu()
|
|
|
{
|
|
|
{
|
|
|
CM_LOCK_MUTEX(mCommandBufferMutex);
|
|
|
@@ -66,7 +75,7 @@ namespace CamelotEngine
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- void RenderSystemContext::playbackCommands()
|
|
|
+ void RenderSystemFrameContext::playbackCommands()
|
|
|
{
|
|
|
#if CM_DEBUG_MODE
|
|
|
RenderSystem* rs = RenderSystemManager::getActive();
|
|
|
@@ -126,7 +135,7 @@ namespace CamelotEngine
|
|
|
CM_THREAD_NOTIFY_ALL(mContextPlaybackDoneCondition)
|
|
|
}
|
|
|
|
|
|
- bool RenderSystemContext::hasReadyCommands()
|
|
|
+ bool RenderSystemFrameContext::hasReadyCommands()
|
|
|
{
|
|
|
CM_LOCK_MUTEX(mCommandBufferMutex);
|
|
|
|
|
|
@@ -136,7 +145,7 @@ namespace CamelotEngine
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- void RenderSystemContext::blockUntilExecuted()
|
|
|
+ void RenderSystemFrameContext::blockUntilExecuted()
|
|
|
{
|
|
|
#if CM_DEBUG_MODE
|
|
|
RenderSystem* rs = RenderSystemManager::getActive();
|
|
|
@@ -153,4 +162,124 @@ namespace CamelotEngine
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /************************************************************************/
|
|
|
+ /* IMMEDIATE CONTEXT */
|
|
|
+ /************************************************************************/
|
|
|
+
|
|
|
+ RenderSystemImmediateContext::RenderSystemImmediateContext(CM_THREAD_ID_TYPE threadId)
|
|
|
+ :RenderSystemContext(threadId)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ AsyncOp RenderSystemImmediateContext::queueReturnCommand(boost::function<void(AsyncOp&)> commandCallback, UINT32 _callbackId)
|
|
|
+ {
|
|
|
+ CM_LOCK_MUTEX(mCommandBufferMutex)
|
|
|
+
|
|
|
+ RenderSystemCommand newCommand(commandCallback, _callbackId);
|
|
|
+ mCommands->push_back(newCommand);
|
|
|
+
|
|
|
+ return newCommand.asyncOp;
|
|
|
+ }
|
|
|
+
|
|
|
+ void RenderSystemImmediateContext::queueCommand(boost::function<void()> commandCallback, UINT32 _callbackId)
|
|
|
+ {
|
|
|
+ CM_LOCK_MUTEX(mCommandBufferMutex)
|
|
|
+
|
|
|
+ RenderSystemCommand newCommand(commandCallback, _callbackId);
|
|
|
+ mCommands->push_back(newCommand);
|
|
|
+ }
|
|
|
+
|
|
|
+ void RenderSystemImmediateContext::submitToGpu()
|
|
|
+ {
|
|
|
+ // Do nothing
|
|
|
+ }
|
|
|
+
|
|
|
+ void RenderSystemImmediateContext::playbackCommands()
|
|
|
+ {
|
|
|
+#if CM_DEBUG_MODE
|
|
|
+ RenderSystem* rs = RenderSystemManager::getActive();
|
|
|
+
|
|
|
+ if(rs->getRenderThreadId() != CM_THREAD_CURRENT_ID)
|
|
|
+ CM_EXCEPT(InternalErrorException, "This method should only be called from the render thread.");
|
|
|
+#endif
|
|
|
+
|
|
|
+ vector<RenderSystemCommand>::type* currentCommands = nullptr;
|
|
|
+ {
|
|
|
+ CM_LOCK_MUTEX(mCommandBufferMutex)
|
|
|
+
|
|
|
+ currentCommands = mCommands;
|
|
|
+ mCommands = new vector<RenderSystemCommand>::type();
|
|
|
+ mIsExecuting = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(currentCommands == nullptr)
|
|
|
+ {
|
|
|
+ {
|
|
|
+ CM_LOCK_MUTEX(mCommandBufferMutex);
|
|
|
+ mIsExecuting = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ CM_THREAD_NOTIFY_ALL(mContextPlaybackDoneCondition)
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ for(auto iter = currentCommands->begin(); iter != currentCommands->end(); ++iter)
|
|
|
+ {
|
|
|
+ RenderSystemCommand command = (*iter);
|
|
|
+
|
|
|
+ if(command.returnsValue)
|
|
|
+ {
|
|
|
+ command.callbackWithReturnValue(command.asyncOp);
|
|
|
+
|
|
|
+ if(!command.asyncOp.hasCompleted())
|
|
|
+ {
|
|
|
+ LOGDBG("Async operation return value wasn't resolved properly. Resolving automatically to nullptr. " \
|
|
|
+ "Make sure to complete the operation before returning from the command callback method.");
|
|
|
+ command.asyncOp.completeOperation(nullptr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ command.callback();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ delete currentCommands;
|
|
|
+
|
|
|
+ {
|
|
|
+ CM_LOCK_MUTEX(mCommandBufferMutex);
|
|
|
+ mIsExecuting = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ CM_THREAD_NOTIFY_ALL(mContextPlaybackDoneCondition)
|
|
|
+ }
|
|
|
+
|
|
|
+ bool RenderSystemImmediateContext::hasReadyCommands()
|
|
|
+ {
|
|
|
+ CM_LOCK_MUTEX(mCommandBufferMutex);
|
|
|
+
|
|
|
+ if(mCommands != nullptr && mCommands->size() > 0)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ void RenderSystemImmediateContext::blockUntilExecuted()
|
|
|
+ {
|
|
|
+#if CM_DEBUG_MODE
|
|
|
+ RenderSystem* rs = RenderSystemManager::getActive();
|
|
|
+
|
|
|
+ if(rs->getRenderThreadId() == CM_THREAD_CURRENT_ID)
|
|
|
+ CM_EXCEPT(InternalErrorException, "This method should never be called from the render thread as it will cause a deadlock.");
|
|
|
+#endif
|
|
|
+
|
|
|
+ {
|
|
|
+ CM_LOCK_MUTEX_NAMED(mCommandBufferMutex, lock);
|
|
|
+ while (mCommands != nullptr && mCommands->size() > 0 || mIsExecuting)
|
|
|
+ {
|
|
|
+ CM_THREAD_WAIT(mContextPlaybackDoneCondition, mCommandBufferMutex, lock)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|