ソースを参照

Merge branch 'release/1.9.x'

rdb 9 年 前
コミット
70f10a70d1

+ 11 - 1
direct/src/p3d/Packager.py

@@ -1848,7 +1848,7 @@ class Packager:
 
         def addEggFile(self, file):
             # Precompile egg files to bam's.
-            np = self.packager.loader.loadModel(file.filename)
+            np = self.packager.loader.loadModel(file.filename, self.packager.loaderOptions)
             if not np:
                 raise Exception('Could not read egg file %s' % (file.filename))
 
@@ -1862,6 +1862,8 @@ class Packager:
             if not bamFile.openRead(file.filename):
                 raise Exception('Could not read bam file %s' % (file.filename))
 
+            bamFile.getReader().setLoaderOptions(self.packager.loaderOptions)
+
             if not bamFile.resolve():
                 raise Exception('Could not resolve bam file %s' % (file.filename))
 
@@ -2492,6 +2494,14 @@ class Packager:
         self.sfxManagerList = None
         self.musicManager = None
 
+        # These options will be used when loading models and textures.  By
+        # default we don't load textures beyond the header and don't store
+        # models in the RAM cache in order to conserve on memory usage.
+        opts = LoaderOptions()
+        opts.setFlags(opts.getFlags() | LoaderOptions.LFNoRamCache)
+        opts.setTextureFlags(opts.getTextureFlags() & ~LoaderOptions.TFPreload)
+        self.loaderOptions = opts
+
         # This is filled in during readPackageDef().
         self.packageList = []
 

+ 4 - 0
direct/src/p3d/panda3d.pdef

@@ -462,6 +462,8 @@ class packp3d(p3d):
 
     mainModule('direct.p3d.packp3d')
 
+    file('packp3d.prc', extract = True, text = "preload-textures false")
+
 
 class ppackage(p3d):
     # As above, a packaging utility.  This is the fully-general ppackage
@@ -475,6 +477,8 @@ class ppackage(p3d):
 
     mainModule('direct.p3d.ppackage')
 
+    file('ppackage.prc', extract = True, text = "preload-textures false")
+
 
 class ppatcher(p3d):
     # A handy utility to go along with ppackage.  This builds

+ 1 - 1
direct/src/showbase/Loader.py

@@ -909,7 +909,7 @@ class Loader(DirectObject):
             orig = origModelList[i].node()
             flat = models[i].node()
             orig.copyAllProperties(flat)
-            orig.replaceNode(flat)
+            flat.replaceNode(orig)
 
         if callback:
             if gotList:

+ 3 - 1
doc/ReleaseNotes

@@ -6,6 +6,7 @@ This issue fixes several bugs that were still found in 1.9.2.
 * Fix crash using wx/tkinter on Mac as long as want-wx/tk is set
 * Fix loading models from 'models' package with models/ prefix
 * Fix random crashes in task system
+* Fix various race conditions causing threading issues
 * Fix memory leaks in BulletTriangleMesh
 * Fix loading old models with MovingPart<LMatrix4f>
 * Improve performance of CPU vertex animation somewhat
@@ -26,12 +27,13 @@ This issue fixes several bugs that were still found in 1.9.2.
 * Fix issues with certain Cg shader inputs in DX9
 * Support uint8 index buffers in DX9
 * Fix occasional frame lag when loading a big model asynchronously
-* Fix race condition reading string config var
 * Fix interrogate parsing issue with "const static"
 * Add back missing libp3pystub.a to Mac OS X SDK
 * Fix RAM caching of 2D texture arrays
 * Fix Ctrl+C interrupt propagation to runtime applications
 * Support for InvSphere, Box and Tube solids in bam2egg
+* Add normalized() method to vectors
+* asyncFlattenStrong with inPlace=True caused node to disappear
 
 ------------------------  RELEASE 1.9.2  ------------------------
 

+ 17 - 7
panda/src/ode/odeTriMeshData.cxx

@@ -54,14 +54,19 @@ print_data(const string &marker) {
 
 void OdeTriMeshData::
 remove_data(OdeTriMeshData *data) {
-  odetrimeshdata_cat.debug() << get_class_type() << "::remove_data(" << data->get_id() << ")" << "\n";
-  nassertv(_tri_mesh_data_map != (TriMeshDataMap *)NULL);
-  TriMeshDataMap::iterator iter;
+  if (odetrimeshdata_cat.is_debug()) {
+    odetrimeshdata_cat.debug()
+      << get_class_type() << "::remove_data(" << data->get_id() << ")" << "\n";
+  }
+  if (_tri_mesh_data_map == (TriMeshDataMap *)NULL) {
+    return;
+  }
 
+  TriMeshDataMap::iterator iter;
   for (iter = _tri_mesh_data_map->begin();
        iter != _tri_mesh_data_map->end();
        ++iter) {
-    if ( iter->second == data ) {
+    if (iter->second == data) {
       break;
     }
   }
@@ -72,7 +77,7 @@ remove_data(OdeTriMeshData *data) {
     for (iter = _tri_mesh_data_map->begin();
          iter != _tri_mesh_data_map->end();
          ++iter) {
-      if ( iter->second == data ) {
+      if (iter->second == data) {
         break;
       }
     }
@@ -150,8 +155,13 @@ operator = (const OdeTriMeshData &other) {
 void OdeTriMeshData::
 process_model(const NodePath& model, bool &use_normals) {
   // TODO: assert if _vertices is something other than 0.
-  ostream &out = odetrimeshdata_cat.debug();
-  out << "process_model(" << model << ")" << "\n";
+  if (odetrimeshdata_cat.is_debug()) {
+    odetrimeshdata_cat.debug()
+      << "process_model(" << model << ")" << "\n";
+  }
+  if (model.is_empty()) {
+    return;
+  }
 
   NodePathCollection geomNodePaths = model.find_all_matches("**/+GeomNode");
   if (model.node()->get_type() == GeomNode::get_class_type()) {

+ 10 - 1
panda/src/putil/copyOnWriteObject.I

@@ -66,13 +66,22 @@ operator = (const CopyOnWriteObject &copy) {
 
 #ifdef COW_THREADED
 /**
- * See CachedTypedWritableReferenceCount::cache_ref().
+ * @see CachedTypedWritableReferenceCount::cache_ref()
  */
 INLINE void CopyOnWriteObject::
 cache_ref() const {
   MutexHolder holder(_lock_mutex);
   CachedTypedWritableReferenceCount::cache_ref();
 }
+
+/**
+ * @see CachedTypedWritableReferenceCount::cache_unref()
+ */
+INLINE bool CopyOnWriteObject::
+cache_unref() const {
+  MutexHolder holder(_lock_mutex);
+  return CachedTypedWritableReferenceCount::cache_unref();
+}
 #endif  // COW_THREADED
 
 /**

+ 1 - 0
panda/src/putil/copyOnWriteObject.h

@@ -48,6 +48,7 @@ PUBLISHED:
 #ifdef COW_THREADED
   virtual bool unref() const;
   INLINE void cache_ref() const;
+  INLINE bool cache_unref() const;
 #endif  // COW_THREADED
 
 protected:

+ 25 - 6
panda/src/putil/copyOnWritePointer.cxx

@@ -12,7 +12,6 @@
  */
 
 #include "copyOnWritePointer.h"
-#include "mutexHolder.h"
 #include "config_util.h"
 #include "config_pipeline.h"
 
@@ -69,7 +68,7 @@ get_write_pointer() {
 
   Thread *current_thread = Thread::get_current_thread();
 
-  MutexHolder holder(_cow_object->_lock_mutex);
+  _cow_object->_lock_mutex.acquire();
   while (_cow_object->_lock_status == CopyOnWriteObject::LS_locked_write &&
          _cow_object->_locking_thread != current_thread) {
     if (util_cat.is_debug()) {
@@ -89,10 +88,20 @@ get_write_pointer() {
         << "Making copy of " << _cow_object->get_type()
         << " because it is locked in read mode.\n";
     }
+
     PT(CopyOnWriteObject) new_object = _cow_object->make_cow_copy();
-    cache_unref_delete(_cow_object);
+
+    // We can't call cache_unref_delete, because we hold the lock.
+    if (!_cow_object->CachedTypedWritableReferenceCount::cache_unref()) {
+      _cow_object->_lock_mutex.release();
+      delete _cow_object;
+    } else {
+      _cow_object->_lock_mutex.release();
+    }
     _cow_object = new_object;
     _cow_object->cache_ref();
+    _cow_object->_lock_status = CopyOnWriteObject::LS_locked_write;
+    _cow_object->_locking_thread = current_thread;
 
   } else if (_cow_object->get_cache_ref_count() > 1) {
     // No one else has it specifically read-locked, but there are other
@@ -106,9 +115,18 @@ get_write_pointer() {
     }
 
     PT(CopyOnWriteObject) new_object = _cow_object->make_cow_copy();
-    cache_unref_delete(_cow_object);
+
+    // We can't call cache_unref_delete, because we hold the lock.
+    if (!_cow_object->CachedTypedWritableReferenceCount::cache_unref()) {
+      _cow_object->_lock_mutex.release();
+      delete _cow_object;
+    } else {
+      _cow_object->_lock_mutex.release();
+    }
     _cow_object = new_object;
     _cow_object->cache_ref();
+    _cow_object->_lock_status = CopyOnWriteObject::LS_locked_write;
+    _cow_object->_locking_thread = current_thread;
 
   } else {
     // No other thread has the pointer locked, and we're the only
@@ -118,9 +136,10 @@ get_write_pointer() {
     // We can't assert that there are no outstanding ordinary references to
     // it, though, since the creator of the object might have saved himself a
     // reference.
+    _cow_object->_lock_status = CopyOnWriteObject::LS_locked_write;
+    _cow_object->_locking_thread = current_thread;
+    _cow_object->_lock_mutex.release();
   }
-  _cow_object->_lock_status = CopyOnWriteObject::LS_locked_write;
-  _cow_object->_locking_thread = current_thread;
 
   return _cow_object;
 }