diff --git a/panda/src/gobj/geomPrimitive.I b/panda/src/gobj/geomPrimitive.I index d8e90ff15f..ae9ed95cb9 100644 --- a/panda/src/gobj/geomPrimitive.I +++ b/panda/src/gobj/geomPrimitive.I @@ -391,7 +391,7 @@ add_vertices(int v1, int v2, int v3, int v4) { //////////////////////////////////////////////////////////////////// // Function: GeomPrimitive::get_index_format -// Access: Protected +// Access: Public // Description: Returns a registered format appropriate for using to // store the index table. //////////////////////////////////////////////////////////////////// @@ -404,7 +404,7 @@ get_index_format() const { //////////////////////////////////////////////////////////////////// // Function: GeomPrimitive::make_index_data -// Access: Protected +// Access: Public // Description: Creates and returns a new, empty index table. //////////////////////////////////////////////////////////////////// INLINE PT(GeomVertexArrayData) GeomPrimitive:: diff --git a/panda/src/gobj/geomPrimitive.h b/panda/src/gobj/geomPrimitive.h index 008bac417d..15639bad4a 100644 --- a/panda/src/gobj/geomPrimitive.h +++ b/panda/src/gobj/geomPrimitive.h @@ -182,7 +182,6 @@ public: bool release(PreparedGraphicsObjects *prepared_objects); int release_all(); -protected: INLINE CPT(GeomVertexArrayFormat) get_index_format() const; INLINE PT(GeomVertexArrayData) make_index_data() const; diff --git a/panda/src/gobj/vertexDataPage.I b/panda/src/gobj/vertexDataPage.I index 7804d8d2e9..947efbd278 100644 --- a/panda/src/gobj/vertexDataPage.I +++ b/panda/src/gobj/vertexDataPage.I @@ -165,6 +165,36 @@ get_num_threads() { return _thread_mgr->get_num_threads(); } +//////////////////////////////////////////////////////////////////// +// Function: VertexDataPage::get_num_pending_reads +// Access: Published, Static +// Description: Returns the number of read requests that are waiting +// to be serviced by a thread. +//////////////////////////////////////////////////////////////////// +INLINE int VertexDataPage:: +get_num_pending_reads() { + MutexHolder holder(_tlock); + if (_thread_mgr == (PageThreadManager *)NULL) { + return 0; + } + return _thread_mgr->get_num_pending_reads(); +} + +//////////////////////////////////////////////////////////////////// +// Function: VertexDataPage::get_num_pending_writes +// Access: Published, Static +// Description: Returns the number of write requests that are waiting +// to be serviced by a thread. +//////////////////////////////////////////////////////////////////// +INLINE int VertexDataPage:: +get_num_pending_writes() { + MutexHolder holder(_tlock); + if (_thread_mgr == (PageThreadManager *)NULL) { + return 0; + } + return _thread_mgr->get_num_pending_writes(); +} + //////////////////////////////////////////////////////////////////// // Function: VertexDataPage::get_page_data // Access: Public diff --git a/panda/src/gobj/vertexDataPage.cxx b/panda/src/gobj/vertexDataPage.cxx index d3fb0d3355..d88c2cbd85 100644 --- a/panda/src/gobj/vertexDataPage.cxx +++ b/panda/src/gobj/vertexDataPage.cxx @@ -154,9 +154,9 @@ VertexDataPage:: //////////////////////////////////////////////////////////////////// // Function: VertexDataPage::stop_threads // Access: Published, Static -// Description: Call this to stop the paging thread, if it was -// started. This may block until all of the thread's -// pending tasks have been completed. +// Description: Call this to stop the paging threads, if they were +// started. This may block until all of the pending +// tasks have been completed. //////////////////////////////////////////////////////////////////// void VertexDataPage:: stop_threads() { @@ -174,6 +174,32 @@ stop_threads() { } } +//////////////////////////////////////////////////////////////////// +// Function: VertexDataPage::flush_threads +// Access: Published, Static +// Description: Waits for all of the pending thread tasks to finish +// before returning. +//////////////////////////////////////////////////////////////////// +void VertexDataPage:: +flush_threads() { + int num_threads = vertex_data_page_threads; + if (num_threads == 0) { + stop_threads(); + return; + } + + PT(PageThreadManager) thread_mgr; + { + MutexHolder holder(_tlock); + thread_mgr = _thread_mgr; + } + + if (thread_mgr != (PageThreadManager *)NULL) { + thread_mgr->stop_threads(); + thread_mgr->start_threads(num_threads); + } +} + //////////////////////////////////////////////////////////////////// // Function: VertexDataPage::make_block // Access: Protected, Virtual @@ -641,14 +667,7 @@ PageThreadManager(int num_threads) : _shutdown(false), _pending_cvar(_tlock) { - _threads.reserve(num_threads); - for (int i = 0; i < num_threads; ++i) { - ostringstream name_strm; - name_strm << "VertexDataPage" << i; - PT(PageThread) thread = new PageThread(this, name_strm.str()); - thread->start(TP_low, true); - _threads.push_back(thread); - } + start_threads(num_threads); } //////////////////////////////////////////////////////////////////// @@ -749,6 +768,49 @@ get_num_threads() const { return (int)_threads.size(); } +//////////////////////////////////////////////////////////////////// +// Function: VertexDataPage::PageThreadManager::get_num_pending_reads +// Access: Public +// Description: Returns the number of read requests waiting on the +// queue. Assumes _tlock is held. +//////////////////////////////////////////////////////////////////// +int VertexDataPage::PageThreadManager:: +get_num_pending_reads() const { + return (int)_pending_reads.size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: VertexDataPage::PageThreadManager::get_num_pending_writes +// Access: Public +// Description: Returns the number of write requests waiting on the +// queue. Assumes _tlock is held. +//////////////////////////////////////////////////////////////////// +int VertexDataPage::PageThreadManager:: +get_num_pending_writes() const { + return (int)_pending_writes.size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: VertexDataPage::PageThreadManager::start_threads +// Access: Public +// Description: Adds the indicated of threads to the list of active +// threads. Assumes _tlock is *not* held. +//////////////////////////////////////////////////////////////////// +void VertexDataPage::PageThreadManager:: +start_threads(int num_threads) { + MutexHolder holder(_tlock); + _shutdown = false; + + _threads.reserve(num_threads); + for (int i = 0; i < num_threads; ++i) { + ostringstream name_strm; + name_strm << "VertexDataPage" << _threads.size(); + PT(PageThread) thread = new PageThread(this, name_strm.str()); + thread->start(TP_low, true); + _threads.push_back(thread); + } +} + //////////////////////////////////////////////////////////////////// // Function: VertexDataPage::PageThreadManager::stop_threads // Access: Public @@ -758,14 +820,16 @@ get_num_threads() const { //////////////////////////////////////////////////////////////////// void VertexDataPage::PageThreadManager:: stop_threads() { + PageThreads threads; { MutexHolder holder(_tlock); _shutdown = true; _pending_cvar.signal_all(); + threads.swap(_threads); } PageThreads::iterator ti; - for (ti = _threads.begin(); ti != _threads.end(); ++ti) { + for (ti = threads.begin(); ti != threads.end(); ++ti) { PageThread *thread = (*ti); thread->join(); } diff --git a/panda/src/gobj/vertexDataPage.h b/panda/src/gobj/vertexDataPage.h index ee23458797..7ed23a7518 100644 --- a/panda/src/gobj/vertexDataPage.h +++ b/panda/src/gobj/vertexDataPage.h @@ -71,7 +71,10 @@ PUBLISHED: INLINE bool save_to_disk(); INLINE static int get_num_threads(); + INLINE static int get_num_pending_reads(); + INLINE static int get_num_pending_writes(); static void stop_threads(); + static void flush_threads(); public: INLINE unsigned char *get_page_data(bool force); @@ -132,6 +135,9 @@ private: void add_page(VertexDataPage *page, RamClass ram_class); void remove_page(VertexDataPage *page); int get_num_threads() const; + int get_num_pending_reads() const; + int get_num_pending_writes() const; + void start_threads(int num_threads); void stop_threads(); private: