Forráskód Böngészése

Make Octree::Raycast() possible to call from worker threads. This doesn't necessarily mean that it's safe to do so, unless you make sure you're not modifying the scene in the main thread at the same time.

Lasse Öörni 10 éve
szülő
commit
bcd2991fa2

+ 4 - 0
Source/Urho3D/Core/WorkQueue.cpp

@@ -65,6 +65,7 @@ WorkQueue::WorkQueue(Context* context) :
     shutDown_(false),
     pausing_(false),
     paused_(false),
+    completing_(false),
     tolerance_(10),
     lastSize_(0),
     maxNonThreadedWorkMs_(5)
@@ -232,6 +233,8 @@ void WorkQueue::Resume()
 
 void WorkQueue::Complete(unsigned priority)
 {
+    completing_ = true;
+
     if (threads_.Size())
     {
         Resume();
@@ -277,6 +280,7 @@ void WorkQueue::Complete(unsigned priority)
     }
 
     PurgeCompleted(priority);
+    completing_ = false;
 }
 
 bool WorkQueue::IsCompleted(unsigned priority) const

+ 4 - 0
Source/Urho3D/Core/WorkQueue.h

@@ -112,6 +112,8 @@ public:
 
     /// Return whether all work with at least the specified priority is finished.
     bool IsCompleted(unsigned priority) const;
+    /// Return whether the queue is currently completing work in the main thread.
+    bool IsCompleting() const { return completing_; }
 
     /// Return the pool tolerance.
     int GetTolerance() const { return tolerance_; }
@@ -147,6 +149,8 @@ private:
     volatile bool pausing_;
     /// Paused flag. Indicates the queue mutex being locked to prevent worker threads using up CPU time.
     bool paused_;
+    /// Completing work in the main thread flag.
+    bool completing_;
     /// Tolerance for the shared pool before it begins to deallocate.
     int tolerance_;
     /// Last size of the shared pool.

+ 3 - 2
Source/Urho3D/Graphics/Octree.cpp

@@ -25,6 +25,7 @@
 #include "../Core/Context.h"
 #include "../Core/CoreEvents.h"
 #include "../Core/Profiler.h"
+#include "../Core/Thread.h"
 #include "../Core/WorkQueue.h"
 #include "../Graphics/DebugRenderer.h"
 #include "../Graphics/Graphics.h"
@@ -514,8 +515,8 @@ void Octree::Raycast(RayOctreeQuery& query) const
 
     WorkQueue* queue = GetSubsystem<WorkQueue>();
 
-    // If no worker threads or no triangle-level testing, do not create work items
-    if (!queue->GetNumThreads() || query.level_ < RAY_TRIANGLE)
+    // If no worker threads or no triangle-level testing, or we are being called from a worker thread do not create work items
+    if (query.level_ < RAY_TRIANGLE || !queue->GetNumThreads() || !Thread::IsMainThread() || queue->IsCompleting())
         GetDrawablesInternal(query);
     else
     {