Browse Source

Merge branch 'master' into vulkan

rdb 9 năm trước cách đây
mục cha
commit
861d5d438e
100 tập tin đã thay đổi với 836 bổ sung822 xóa
  1. 0 4
      contrib/src/ai/aiBehaviors.h
  2. 0 5
      contrib/src/ai/aiCharacter.h
  3. 0 4
      contrib/src/ai/aiGlobals.h
  4. 0 5
      contrib/src/ai/aiWorld.h
  5. 3 3
      contrib/src/ai/obstacleAvoidance.cxx
  6. 1 1
      direct/src/dcparser/dcArrayParameter.h
  7. 1 1
      direct/src/dcparser/dcAtomicField.h
  8. 1 1
      direct/src/dcparser/dcClass.h
  9. 1 1
      direct/src/dcparser/dcClassParameter.h
  10. 1 1
      direct/src/dcparser/dcDeclaration.h
  11. 1 1
      direct/src/dcparser/dcField.h
  12. 1 1
      direct/src/dcparser/dcFile.h
  13. 1 1
      direct/src/dcparser/dcKeyword.h
  14. 1 1
      direct/src/dcparser/dcKeywordList.h
  15. 1 1
      direct/src/dcparser/dcMolecularField.h
  16. 1 1
      direct/src/dcparser/dcPackData.h
  17. 2 2
      direct/src/dcparser/dcPacker.h
  18. 1 1
      direct/src/dcparser/dcPackerCatalog.h
  19. 1 1
      direct/src/dcparser/dcPackerInterface.h
  20. 1 1
      direct/src/dcparser/dcParameter.h
  21. 1 1
      direct/src/dcparser/dcSimpleParameter.h
  22. 1 1
      direct/src/dcparser/dcSwitch.h
  23. 1 1
      direct/src/dcparser/dcSwitchParameter.h
  24. 1 1
      direct/src/dcparser/dcTypedef.h
  25. 22 2
      direct/src/distributed/cConnectionRepository.cxx
  26. 4 4
      direct/src/p3d/FileSpec.py
  27. 0 2
      direct/src/plugin/p3dCInstance.h
  28. 49 39
      direct/src/showbase/Loader.py
  29. 4 1
      direct/src/showutil/FreezeTool.py
  30. 10 10
      direct/src/stdpy/thread.py
  31. 10 0
      doc/ReleaseNotes
  32. 0 2
      dtool/src/cppparser/cppManifest.cxx
  33. 3 4
      dtool/src/cppparser/cppPreprocessor.cxx
  34. 1 1
      dtool/src/cppparser/cppToken.cxx
  35. 11 9
      dtool/src/dtoolbase/dtoolbase.h
  36. 6 0
      dtool/src/dtoolbase/typeRegistry.cxx
  37. 1 1
      dtool/src/dtoolutil/pandaFileStreamBuf.cxx
  38. 49 5
      dtool/src/interrogate/interfaceMakerPythonNative.cxx
  39. 2 1
      dtool/src/interrogate/interfaceMakerPythonNative.h
  40. 0 4
      dtool/src/interrogate/interrogate.cxx
  41. 4 4
      dtool/src/interrogate/interrogateBuilder.cxx
  42. 0 4
      dtool/src/interrogate/interrogate_module.cxx
  43. 1 1
      dtool/src/interrogate/typeManager.cxx
  44. 1 1
      dtool/src/interrogatedb/extension.h
  45. 8 0
      dtool/src/interrogatedb/py_panda.I
  46. 2 0
      dtool/src/interrogatedb/py_panda.cxx
  47. 4 3
      dtool/src/interrogatedb/py_panda.h
  48. 1 1
      dtool/src/parser-inc/Python.h
  49. 21 9
      dtool/src/prc/configVariableFilename.cxx
  50. 1 2
      dtool/src/prc/configVariableString.I
  51. 21 0
      dtool/src/prc/configVariableString.cxx
  52. 3 0
      dtool/src/prc/configVariableString.h
  53. 0 1
      dtool/src/test_interrogate/test_interrogate.cxx
  54. 136 126
      makepanda/makepanda.py
  55. 0 4
      panda/src/android/pview.cxx
  56. 17 0
      panda/src/chan/animChannelFixed.cxx
  57. 2 0
      panda/src/chan/animChannelFixed.h
  58. 1 0
      panda/src/chan/p3chan_composite1.cxx
  59. 1 1
      panda/src/char/character.cxx
  60. 0 3
      panda/src/display/displayRegion.cxx
  61. 27 8
      panda/src/display/graphicsEngine.cxx
  62. 2 0
      panda/src/display/graphicsPipeSelection.cxx
  63. 1 2
      panda/src/display/graphicsStateGuardian.cxx
  64. 0 10
      panda/src/display/standardMunger.I
  65. 16 23
      panda/src/display/standardMunger.cxx
  66. 0 3
      panda/src/display/standardMunger.h
  67. 0 4
      panda/src/downloadertools/apply_patch.cxx
  68. 0 4
      panda/src/downloadertools/build_patch.cxx
  69. 0 4
      panda/src/downloadertools/check_adler.cxx
  70. 0 4
      panda/src/downloadertools/check_crc.cxx
  71. 0 4
      panda/src/downloadertools/check_md5.cxx
  72. 0 4
      panda/src/downloadertools/multify.cxx
  73. 0 4
      panda/src/downloadertools/pdecrypt.cxx
  74. 0 1
      panda/src/downloadertools/pencrypt.cxx
  75. 0 4
      panda/src/downloadertools/punzip.cxx
  76. 0 4
      panda/src/downloadertools/pzip.cxx
  77. 0 4
      panda/src/downloadertools/show_ddb.cxx
  78. 59 30
      panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx
  79. 7 7
      panda/src/dxgsg9/dxGraphicsStateGuardian9.h
  80. 30 23
      panda/src/dxgsg9/dxIndexBufferContext9.cxx
  81. 1 1
      panda/src/dxgsg9/dxOcclusionQueryContext9.h
  82. 1 1
      panda/src/dxgsg9/dxShaderContext9.I
  83. 180 221
      panda/src/dxgsg9/dxShaderContext9.cxx
  84. 36 23
      panda/src/dxgsg9/dxShaderContext9.h
  85. 5 5
      panda/src/dxgsg9/dxVertexBufferContext9.cxx
  86. 4 4
      panda/src/dxgsg9/dxVertexBufferContext9.h
  87. 4 2
      panda/src/dxgsg9/wdxGraphicsBuffer9.cxx
  88. 1 5
      panda/src/egg/eggVertex.cxx
  89. 0 39
      panda/src/event/asyncTask.cxx
  90. 0 10
      panda/src/event/asyncTask.h
  91. 0 34
      panda/src/event/pythonTask.I
  92. 24 18
      panda/src/event/pythonTask.cxx
  93. 2 5
      panda/src/event/pythonTask.h
  94. 1 1
      panda/src/express/memoryInfo.cxx
  95. 2 2
      panda/src/express/nodeReferenceCount.I
  96. 2 3
      panda/src/express/nodeReferenceCount.h
  97. 0 1
      panda/src/express/ordered_vector.T
  98. 0 4
      panda/src/express/pointerToArray.h
  99. 12 6
      panda/src/express/pointerToArray_ext.I
  100. 0 4
      panda/src/express/pointerToArray_ext.h

+ 0 - 4
contrib/src/ai/aiBehaviors.h

@@ -11,10 +11,6 @@
  * @date 2009-09-08
  * @date 2009-09-08
  */
  */
 
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
 #ifndef _AIBEHAVIORS_H
 #ifndef _AIBEHAVIORS_H
 #define _AIBEHAVIORS_H
 #define _AIBEHAVIORS_H
 
 

+ 0 - 5
contrib/src/ai/aiCharacter.h

@@ -11,11 +11,6 @@
  * @date 2009-09-08
  * @date 2009-09-08
  */
  */
 
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
-
 #ifndef _AICHARACTER_H
 #ifndef _AICHARACTER_H
 #define _AICHARACTER_H
 #define _AICHARACTER_H
 
 

+ 0 - 4
contrib/src/ai/aiGlobals.h

@@ -11,10 +11,6 @@
  * @date 2009-09-08
  * @date 2009-09-08
  */
  */
 
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
 #ifndef _AI_GLOBALS_H
 #ifndef _AI_GLOBALS_H
 #define _AI_GLOBALS_H
 #define _AI_GLOBALS_H
 
 

+ 0 - 5
contrib/src/ai/aiWorld.h

@@ -11,11 +11,6 @@
  * @date 2009-09-08
  * @date 2009-09-08
  */
  */
 
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
-
 #ifndef _AIWORLD_H
 #ifndef _AIWORLD_H
 #define _AIWORLD_H
 #define _AIWORLD_H
 
 

+ 3 - 3
contrib/src/ai/obstacleAvoidance.cxx

@@ -34,7 +34,7 @@ obstacle_detection() {
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
   LVecBase3 avoidance(0.0, 0.0, 0.0);
   LVecBase3 avoidance(0.0, 0.0, 0.0);
   double distance = 0x7fff ;
   double distance = 0x7fff ;
-  double expanded_radius;
+  double expanded_radius = 0;
   LVecBase3 to_obstacle;
   LVecBase3 to_obstacle;
   LVecBase3 prev_avoidance;
   LVecBase3 prev_avoidance;
   for(unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) {
   for(unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) {
@@ -89,8 +89,8 @@ do_obstacle_avoidance() {
   CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();
   CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();
   PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
   PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
-  double distance_needed = offset.length() - bsphere->get_radius() - np_sphere->get_radius();
-  if((obstacle_detection())) {
+
+  if (obstacle_detection()) {
     LVecBase3 direction = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
     LVecBase3 direction = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
     direction.normalize();
     direction.normalize();
     float forward_component = offset.dot(direction);
     float forward_component = offset.dot(direction);

+ 1 - 1
direct/src/dcparser/dcArrayParameter.h

@@ -23,7 +23,7 @@
  * parameter type accepts an arbitrary (or possibly fixed) number of nested
  * parameter type accepts an arbitrary (or possibly fixed) number of nested
  * fields, all of which are of the same type.
  * fields, all of which are of the same type.
  */
  */
-class EXPCL_DIRECT DCArrayParameter : public DCParameter {
+class DCArrayParameter : public DCParameter {
 public:
 public:
   DCArrayParameter(DCParameter *element_type,
   DCArrayParameter(DCParameter *element_type,
                    const DCUnsignedIntRange &size = DCUnsignedIntRange());
                    const DCUnsignedIntRange &size = DCUnsignedIntRange());

+ 1 - 1
direct/src/dcparser/dcAtomicField.h

@@ -27,7 +27,7 @@
  * This defines an interface to the Distributed Class, and is always
  * This defines an interface to the Distributed Class, and is always
  * implemented as a remote procedure method.
  * implemented as a remote procedure method.
  */
  */
-class EXPCL_DIRECT DCAtomicField : public DCField {
+class DCAtomicField : public DCField {
 public:
 public:
   DCAtomicField(const string &name, DCClass *dclass, bool bogus_field);
   DCAtomicField(const string &name, DCClass *dclass, bool bogus_field);
   virtual ~DCAtomicField();
   virtual ~DCAtomicField();

+ 1 - 1
direct/src/dcparser/dcClass.h

@@ -41,7 +41,7 @@ class DCParameter;
 /**
 /**
  * Defines a particular DistributedClass as read from an input .dc file.
  * Defines a particular DistributedClass as read from an input .dc file.
  */
  */
-class EXPCL_DIRECT DCClass : public DCDeclaration {
+class DCClass : public DCDeclaration {
 public:
 public:
   DCClass(DCFile *dc_file, const string &name,
   DCClass(DCFile *dc_file, const string &name,
           bool is_struct, bool bogus_class);
           bool is_struct, bool bogus_class);

+ 1 - 1
direct/src/dcparser/dcClassParameter.h

@@ -23,7 +23,7 @@ class DCClass;
  * This represents a class (or struct) object used as a parameter itself.
  * This represents a class (or struct) object used as a parameter itself.
  * This means that all the fields of the class get packed into the message.
  * This means that all the fields of the class get packed into the message.
  */
  */
-class EXPCL_DIRECT DCClassParameter : public DCParameter {
+class DCClassParameter : public DCParameter {
 public:
 public:
   DCClassParameter(const DCClass *dclass);
   DCClassParameter(const DCClass *dclass);
   DCClassParameter(const DCClassParameter &copy);
   DCClassParameter(const DCClassParameter &copy);

+ 1 - 1
direct/src/dcparser/dcDeclaration.h

@@ -26,7 +26,7 @@ class DCSwitch;
  * only purpose is so that classes and typedefs can be stored in one list
  * only purpose is so that classes and typedefs can be stored in one list
  * together so they can be ordered correctly on output.
  * together so they can be ordered correctly on output.
  */
  */
-class EXPCL_DIRECT DCDeclaration {
+class DCDeclaration {
 public:
 public:
   virtual ~DCDeclaration();
   virtual ~DCDeclaration();
 
 

+ 1 - 1
direct/src/dcparser/dcField.h

@@ -34,7 +34,7 @@ class HashGenerator;
 /**
 /**
  * A single field of a Distributed Class, either atomic or molecular.
  * A single field of a Distributed Class, either atomic or molecular.
  */
  */
-class EXPCL_DIRECT DCField : public DCPackerInterface, public DCKeywordList {
+class DCField : public DCPackerInterface, public DCKeywordList {
 public:
 public:
   DCField();
   DCField();
   DCField(const string &name, DCClass *dclass);
   DCField(const string &name, DCClass *dclass);

+ 1 - 1
direct/src/dcparser/dcFile.h

@@ -29,7 +29,7 @@ class DCDeclaration;
  * Represents the complete list of Distributed Class descriptions as read from
  * Represents the complete list of Distributed Class descriptions as read from
  * a .dc file.
  * a .dc file.
  */
  */
-class EXPCL_DIRECT DCFile {
+class DCFile {
 PUBLISHED:
 PUBLISHED:
   DCFile();
   DCFile();
   ~DCFile();
   ~DCFile();

+ 1 - 1
direct/src/dcparser/dcKeyword.h

@@ -25,7 +25,7 @@ class HashGenerator;
  * define a communication property associated with a field, for instance
  * define a communication property associated with a field, for instance
  * "broadcast" or "airecv".
  * "broadcast" or "airecv".
  */
  */
-class EXPCL_DIRECT DCKeyword : public DCDeclaration {
+class DCKeyword : public DCDeclaration {
 public:
 public:
   DCKeyword(const string &name, int historical_flag = ~0);
   DCKeyword(const string &name, int historical_flag = ~0);
   virtual ~DCKeyword();
   virtual ~DCKeyword();

+ 1 - 1
direct/src/dcparser/dcKeywordList.h

@@ -23,7 +23,7 @@ class HashGenerator;
  * This is a list of keywords (see DCKeyword) that may be set on a particular
  * This is a list of keywords (see DCKeyword) that may be set on a particular
  * field.
  * field.
  */
  */
-class EXPCL_DIRECT DCKeywordList {
+class DCKeywordList {
 public:
 public:
   DCKeywordList();
   DCKeywordList();
   DCKeywordList(const DCKeywordList &copy);
   DCKeywordList(const DCKeywordList &copy);

+ 1 - 1
direct/src/dcparser/dcMolecularField.h

@@ -25,7 +25,7 @@ class DCParameter;
  * This represents a combination of two or more related atomic fields, that
  * This represents a combination of two or more related atomic fields, that
  * will often be treated as a unit.
  * will often be treated as a unit.
  */
  */
-class EXPCL_DIRECT DCMolecularField : public DCField {
+class DCMolecularField : public DCField {
 public:
 public:
   DCMolecularField(const string &name, DCClass *dclass);
   DCMolecularField(const string &name, DCClass *dclass);
 
 

+ 1 - 1
direct/src/dcparser/dcPackData.h

@@ -19,7 +19,7 @@
 /**
 /**
  * This is a block of data that receives the results of DCPacker.
  * This is a block of data that receives the results of DCPacker.
  */
  */
-class EXPCL_DIRECT DCPackData {
+class DCPackData {
 PUBLISHED:
 PUBLISHED:
   INLINE DCPackData();
   INLINE DCPackData();
   INLINE ~DCPackData();
   INLINE ~DCPackData();

+ 2 - 2
direct/src/dcparser/dcPacker.h

@@ -31,7 +31,7 @@ class DCSwitchParameter;
  * See also direct/src/doc/dcPacker.txt for a more complete description and
  * See also direct/src/doc/dcPacker.txt for a more complete description and
  * examples of using this class.
  * examples of using this class.
  */
  */
-class EXPCL_DIRECT DCPacker {
+class DCPacker {
 PUBLISHED:
 PUBLISHED:
   DCPacker();
   DCPacker();
   ~DCPacker();
   ~DCPacker();
@@ -216,7 +216,7 @@ private:
   const DCPackerCatalog *_catalog;
   const DCPackerCatalog *_catalog;
   const DCPackerCatalog::LiveCatalog *_live_catalog;
   const DCPackerCatalog::LiveCatalog *_live_catalog;
 
 
-  class EXPCL_DIRECT StackElement {
+  class StackElement {
   public:
   public:
     // As an optimization, we implement operator new and delete here to
     // As an optimization, we implement operator new and delete here to
     // minimize allocation overhead during push() and pop().
     // minimize allocation overhead during push() and pop().

+ 1 - 1
direct/src/dcparser/dcPackerCatalog.h

@@ -26,7 +26,7 @@ class DCSwitchParameter;
  * requested from a particular field; its ownership is retained by the field
  * requested from a particular field; its ownership is retained by the field
  * so it must not be deleted.
  * so it must not be deleted.
  */
  */
-class EXPCL_DIRECT DCPackerCatalog {
+class DCPackerCatalog {
 private:
 private:
   DCPackerCatalog(const DCPackerInterface *root);
   DCPackerCatalog(const DCPackerInterface *root);
   DCPackerCatalog(const DCPackerCatalog &copy);
   DCPackerCatalog(const DCPackerCatalog &copy);

+ 1 - 1
direct/src/dcparser/dcPackerInterface.h

@@ -64,7 +64,7 @@ END_PUBLISH
  * Normally these methods are called only by the DCPacker object; the user
  * Normally these methods are called only by the DCPacker object; the user
  * wouldn't normally call these directly.
  * wouldn't normally call these directly.
  */
  */
-class EXPCL_DIRECT DCPackerInterface {
+class DCPackerInterface {
 public:
 public:
   DCPackerInterface(const string &name = string());
   DCPackerInterface(const string &name = string());
   DCPackerInterface(const DCPackerInterface &copy);
   DCPackerInterface(const DCPackerInterface &copy);

+ 1 - 1
direct/src/dcparser/dcParameter.h

@@ -32,7 +32,7 @@ class HashGenerator;
  * This may also be a typedef reference to another type, which has the same
  * This may also be a typedef reference to another type, which has the same
  * properties as the referenced type, but a different name.
  * properties as the referenced type, but a different name.
  */
  */
-class EXPCL_DIRECT DCParameter : public DCField {
+class DCParameter : public DCField {
 protected:
 protected:
   DCParameter();
   DCParameter();
   DCParameter(const DCParameter &copy);
   DCParameter(const DCParameter &copy);

+ 1 - 1
direct/src/dcparser/dcSimpleParameter.h

@@ -25,7 +25,7 @@
  * divisor, which is meaningful only for the numeric type elements (and
  * divisor, which is meaningful only for the numeric type elements (and
  * represents a fixed-point numeric convention).
  * represents a fixed-point numeric convention).
  */
  */
-class EXPCL_DIRECT DCSimpleParameter : public DCParameter {
+class DCSimpleParameter : public DCParameter {
 public:
 public:
   DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
   DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
   DCSimpleParameter(const DCSimpleParameter &copy);
   DCSimpleParameter(const DCSimpleParameter &copy);

+ 1 - 1
direct/src/dcparser/dcSwitch.h

@@ -27,7 +27,7 @@ class DCField;
  * and represents two or more alternative unpacking schemes based on the first
  * and represents two or more alternative unpacking schemes based on the first
  * field read.
  * field read.
  */
  */
-class EXPCL_DIRECT DCSwitch : public DCDeclaration {
+class DCSwitch : public DCDeclaration {
 public:
 public:
   DCSwitch(const string &name, DCField *key_parameter);
   DCSwitch(const string &name, DCField *key_parameter);
   virtual ~DCSwitch();
   virtual ~DCSwitch();

+ 1 - 1
direct/src/dcparser/dcSwitchParameter.h

@@ -23,7 +23,7 @@ class DCSwitch;
  * This represents a switch object used as a parameter itself, which packs the
  * This represents a switch object used as a parameter itself, which packs the
  * appropriate fields of the switch into the message.
  * appropriate fields of the switch into the message.
  */
  */
-class EXPCL_DIRECT DCSwitchParameter : public DCParameter {
+class DCSwitchParameter : public DCParameter {
 public:
 public:
   DCSwitchParameter(const DCSwitch *dswitch);
   DCSwitchParameter(const DCSwitch *dswitch);
   DCSwitchParameter(const DCSwitchParameter &copy);
   DCSwitchParameter(const DCSwitchParameter &copy);

+ 1 - 1
direct/src/dcparser/dcTypedef.h

@@ -23,7 +23,7 @@ class DCParameter;
  * This represents a single typedef declaration in the dc file.  It assigns a
  * This represents a single typedef declaration in the dc file.  It assigns a
  * particular type to a new name, just like a C typedef.
  * particular type to a new name, just like a C typedef.
  */
  */
-class EXPCL_DIRECT DCTypedef : public DCDeclaration {
+class DCTypedef : public DCDeclaration {
 public:
 public:
   DCTypedef(DCParameter *parameter, bool implicit = false);
   DCTypedef(DCParameter *parameter, bool implicit = false);
   DCTypedef(const string &name);
   DCTypedef(const string &name);

+ 22 - 2
direct/src/distributed/cConnectionRepository.cxx

@@ -402,8 +402,28 @@ send_datagram(const Datagram &dg) {
   }
   }
 
 
 #ifdef WANT_NATIVE_NET
 #ifdef WANT_NATIVE_NET
-  if(_native)
-    return _bdc.SendMessage(dg);
+  if (_native) {
+    bool result = _bdc.SendMessage();
+    if (!result && _bdc.IsConnected()) {
+#ifdef HAVE_PYTHON
+      ostringstream s;
+
+#if PY_VERSION_HEX >= 0x03030000
+      PyObject *exc_type = PyExc_ConnectionError;
+#else
+      PyObject *exc_type = PyExc_OSError;
+#endif
+
+      s << endl << "Error sending message: " << endl;
+      msg.dump_hex(s);
+      s << "Message data: " << msg.get_data() << endl;
+
+      string message = s.str();
+      PyErr_SetString(exc_type, message.c_str());
+#endif
+    }
+    return result;
+  }
 #endif
 #endif
 
 
 #ifdef HAVE_NET
 #ifdef HAVE_NET

+ 4 - 4
direct/src/p3d/FileSpec.py

@@ -33,7 +33,7 @@ class FileSpec:
         if st is None:
         if st is None:
             st = os.stat(pathname.toOsSpecific())
             st = os.stat(pathname.toOsSpecific())
         self.size = st.st_size
         self.size = st.st_size
-        self.timestamp = st.st_mtime
+        self.timestamp = int(st.st_mtime)
 
 
         self.readHash(pathname)
         self.readHash(pathname)
 
 
@@ -124,7 +124,7 @@ class FileSpec:
                 self.__correctHash(packageDir, pathname, st, notify)
                 self.__correctHash(packageDir, pathname, st, notify)
             return False
             return False
 
 
-        if st.st_mtime == self.timestamp:
+        if int(st.st_mtime) == self.timestamp:
             # If the size is right and the timestamp is right, the
             # If the size is right and the timestamp is right, the
             # file passes.
             # file passes.
             if notify:
             if notify:
@@ -198,7 +198,7 @@ class FileSpec:
         # The hash is OK.  If the timestamp is wrong, change it back
         # The hash is OK.  If the timestamp is wrong, change it back
         # to what we expect it to be, so we can quick-verify it
         # to what we expect it to be, so we can quick-verify it
         # successfully next time.
         # successfully next time.
-        if st.st_mtime != self.timestamp:
+        if int(st.st_mtime) != self.timestamp:
             self.__updateTimestamp(pathname, st)
             self.__updateTimestamp(pathname, st)
 
 
         return True
         return True
@@ -219,7 +219,7 @@ class FileSpec:
         if notify:
         if notify:
             notify.info("Correcting timestamp of %s to %d (%s)" % (
             notify.info("Correcting timestamp of %s to %d (%s)" % (
                 self.filename, st.st_mtime, time.asctime(time.localtime(st.st_mtime))))
                 self.filename, st.st_mtime, time.asctime(time.localtime(st.st_mtime))))
-        self.timestamp = st.st_mtime
+        self.timestamp = int(st.st_mtime)
 
 
     def checkHash(self, packageDir, pathname, st):
     def checkHash(self, packageDir, pathname, st):
         """ Returns true if the file has the expected md5 hash, false
         """ Returns true if the file has the expected md5 hash, false

+ 0 - 2
direct/src/plugin/p3dCInstance.h

@@ -21,8 +21,6 @@
 #include "get_tinyxml.h"
 #include "get_tinyxml.h"
 #include "windowHandle.h"
 #include "windowHandle.h"
 
 
-#include <Python.h>
-
 class P3DSession;
 class P3DSession;
 
 
 /**
 /**

+ 49 - 39
direct/src/showbase/Loader.py

@@ -28,7 +28,7 @@ class Loader(DirectObject):
             self.extraArgs = extraArgs
             self.extraArgs = extraArgs
             self.numRemaining = numObjects
             self.numRemaining = numObjects
             self.cancelled = False
             self.cancelled = False
-            self.requests = {}
+            self.requests = set()
 
 
         def gotObject(self, index, object):
         def gotObject(self, index, object):
             self.objects[index] = object
             self.objects[index] = object
@@ -45,6 +45,8 @@ class Loader(DirectObject):
         self.base = base
         self.base = base
         self.loader = PandaLoader.getGlobalPtr()
         self.loader = PandaLoader.getGlobalPtr()
 
 
+        self.__requests = {}
+
         self.hook = "async_loader_%s" % (Loader.loaderIndex)
         self.hook = "async_loader_%s" % (Loader.loaderIndex)
         Loader.loaderIndex += 1
         Loader.loaderIndex += 1
         self.accept(self.hook, self.__gotAsyncObject)
         self.accept(self.hook, self.__gotAsyncObject)
@@ -116,7 +118,7 @@ class Loader(DirectObject):
         """
         """
 
 
         assert Loader.notify.debug("Loading model: %s" % (modelPath))
         assert Loader.notify.debug("Loading model: %s" % (modelPath))
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
             loaderOptions = LoaderOptions()
         else:
         else:
             loaderOptions = LoaderOptions(loaderOptions)
             loaderOptions = LoaderOptions(loaderOptions)
@@ -156,7 +158,7 @@ class Loader(DirectObject):
             result = []
             result = []
             for modelPath in modelList:
             for modelPath in modelList:
                 node = self.loader.loadSync(Filename(modelPath), loaderOptions)
                 node = self.loader.loadSync(Filename(modelPath), loaderOptions)
-                if (node != None):
+                if node is not None:
                     nodePath = NodePath(node)
                     nodePath = NodePath(node)
                 else:
                 else:
                     nodePath = None
                     nodePath = None
@@ -179,16 +181,16 @@ class Loader(DirectObject):
             # callback (passing it the models on the parameter list).
             # callback (passing it the models on the parameter list).
 
 
             cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
             cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
-            i=0
+            i = 0
             for modelPath in modelList:
             for modelPath in modelList:
                 request = self.loader.makeAsyncRequest(Filename(modelPath), loaderOptions)
                 request = self.loader.makeAsyncRequest(Filename(modelPath), loaderOptions)
                 if priority is not None:
                 if priority is not None:
                     request.setPriority(priority)
                     request.setPriority(priority)
                 request.setDoneEvent(self.hook)
                 request.setDoneEvent(self.hook)
-                request.setPythonObject((cb, i))
-                i+=1
                 self.loader.loadAsync(request)
                 self.loader.loadAsync(request)
-                cb.requests[request] = True
+                cb.requests.add(request)
+                self.__requests[request] = (cb, i)
+                i += 1
             return cb
             return cb
 
 
     def cancelRequest(self, cb):
     def cancelRequest(self, cb):
@@ -200,6 +202,7 @@ class Loader(DirectObject):
             cb.cancelled = True
             cb.cancelled = True
             for request in cb.requests:
             for request in cb.requests:
                 self.loader.remove(request)
                 self.loader.remove(request)
+                del self.__requests[request]
             cb.requests = None
             cb.requests = None
 
 
     def isRequestPending(self, cb):
     def isRequestPending(self, cb):
@@ -273,7 +276,7 @@ class Loader(DirectObject):
             # to resolve it for us.
             # to resolve it for us.
             options = LoaderOptions(LoaderOptions.LFSearch | LoaderOptions.LFNoDiskCache | LoaderOptions.LFCacheOnly)
             options = LoaderOptions(LoaderOptions.LFSearch | LoaderOptions.LFNoDiskCache | LoaderOptions.LFCacheOnly)
             modelNode = self.loader.loadSync(Filename(model), options)
             modelNode = self.loader.loadSync(Filename(model), options)
-            if modelNode == None:
+            if modelNode is None:
                 # Model not found.
                 # Model not found.
                 assert Loader.notify.debug("Unloading model not loaded: %s" % (model))
                 assert Loader.notify.debug("Unloading model not loaded: %s" % (model))
                 return
                 return
@@ -293,7 +296,7 @@ class Loader(DirectObject):
         a callback is used, the model is saved asynchronously, and the
         a callback is used, the model is saved asynchronously, and the
         true/false status is passed to the callback function. """
         true/false status is passed to the callback function. """
 
 
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
             loaderOptions = LoaderOptions()
         else:
         else:
             loaderOptions = LoaderOptions(loaderOptions)
             loaderOptions = LoaderOptions(loaderOptions)
@@ -342,16 +345,16 @@ class Loader(DirectObject):
             # callback (passing it the models on the parameter list).
             # callback (passing it the models on the parameter list).
 
 
             cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
             cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
-            i=0
+            i = 0
             for modelPath, node in modelList:
             for modelPath, node in modelList:
                 request = self.loader.makeAsyncSaveRequest(Filename(modelPath), loaderOptions, node)
                 request = self.loader.makeAsyncSaveRequest(Filename(modelPath), loaderOptions, node)
                 if priority is not None:
                 if priority is not None:
                     request.setPriority(priority)
                     request.setPriority(priority)
                 request.setDoneEvent(self.hook)
                 request.setDoneEvent(self.hook)
-                request.setPythonObject((cb, i))
-                i+=1
                 self.loader.saveAsync(request)
                 self.loader.saveAsync(request)
-                cb.requests[request] = True
+                cb.requests.add(request)
+                self.__requests[request] = (cb, i)
+                i += 1
             return cb
             return cb
 
 
 
 
@@ -496,7 +499,7 @@ class Loader(DirectObject):
             phaseChecker(modelPath, loaderOptions)
             phaseChecker(modelPath, loaderOptions)
 
 
         font = FontPool.loadFont(modelPath)
         font = FontPool.loadFont(modelPath)
-        if font == None:
+        if font is None:
             if not okMissing:
             if not okMissing:
                 message = 'Could not load font file: %s' % (modelPath)
                 message = 'Could not load font file: %s' % (modelPath)
                 raise IOError(message)
                 raise IOError(message)
@@ -506,21 +509,21 @@ class Loader(DirectObject):
 
 
         # The following properties may only be set for dynamic fonts.
         # The following properties may only be set for dynamic fonts.
         if hasattr(font, "setPointSize"):
         if hasattr(font, "setPointSize"):
-            if pointSize != None:
+            if pointSize is not None:
                 font.setPointSize(pointSize)
                 font.setPointSize(pointSize)
-            if pixelsPerUnit != None:
+            if pixelsPerUnit is not None:
                 font.setPixelsPerUnit(pixelsPerUnit)
                 font.setPixelsPerUnit(pixelsPerUnit)
-            if scaleFactor != None:
+            if scaleFactor is not None:
                 font.setScaleFactor(scaleFactor)
                 font.setScaleFactor(scaleFactor)
-            if textureMargin != None:
+            if textureMargin is not None:
                 font.setTextureMargin(textureMargin)
                 font.setTextureMargin(textureMargin)
-            if polyMargin != None:
+            if polyMargin is not None:
                 font.setPolyMargin(polyMargin)
                 font.setPolyMargin(polyMargin)
-            if minFilter != None:
+            if minFilter is not None:
                 font.setMinfilter(minFilter)
                 font.setMinfilter(minFilter)
-            if magFilter != None:
+            if magFilter is not None:
                 font.setMagfilter(magFilter)
                 font.setMagfilter(magFilter)
-            if anisotropicDegree != None:
+            if anisotropicDegree is not None:
                 font.setAnisotropicDegree(anisotropicDegree)
                 font.setAnisotropicDegree(anisotropicDegree)
             if color:
             if color:
                 font.setFg(color)
                 font.setFg(color)
@@ -577,10 +580,10 @@ class Loader(DirectObject):
         the texture and the number of expected mipmap images.
         the texture and the number of expected mipmap images.
 
 
         If minfilter or magfilter is not None, they should be a symbol
         If minfilter or magfilter is not None, they should be a symbol
-        like Texture.FTLinear or Texture.FTNearest.  (minfilter may be
-        further one of the Mipmap filter type symbols.)  These specify
-        the filter mode that will automatically be applied to the
-        texture when it is loaded.  Note that this setting may
+        like SamplerState.FTLinear or SamplerState.FTNearest.  (minfilter
+        may be further one of the Mipmap filter type symbols.)  These
+        specify the filter mode that will automatically be applied to
+        the texture when it is loaded.  Note that this setting may
         override the texture's existing settings, even if it has
         override the texture's existing settings, even if it has
         already been loaded.  See egg-texture-cards for a more robust
         already been loaded.  See egg-texture-cards for a more robust
         way to apply per-texture filter types and settings.
         way to apply per-texture filter types and settings.
@@ -596,7 +599,7 @@ class Loader(DirectObject):
         left image and '1' for the right image.  Larger numbers are
         left image and '1' for the right image.  Larger numbers are
         also allowed if you need more than two views.
         also allowed if you need more than two views.
         """
         """
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
             loaderOptions = LoaderOptions()
         else:
         else:
             loaderOptions = LoaderOptions(loaderOptions)
             loaderOptions = LoaderOptions(loaderOptions)
@@ -657,7 +660,7 @@ class Loader(DirectObject):
         numbered 8 - 15 will be part of the right eye view.
         numbered 8 - 15 will be part of the right eye view.
         """
         """
         assert Loader.notify.debug("Loading 3-D texture: %s" % (texturePattern))
         assert Loader.notify.debug("Loading 3-D texture: %s" % (texturePattern))
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
             loaderOptions = LoaderOptions()
         else:
         else:
             loaderOptions = LoaderOptions(loaderOptions)
             loaderOptions = LoaderOptions(loaderOptions)
@@ -711,7 +714,7 @@ class Loader(DirectObject):
         and each six images will define a new view.
         and each six images will define a new view.
         """
         """
         assert Loader.notify.debug("Loading cube map: %s" % (texturePattern))
         assert Loader.notify.debug("Loading cube map: %s" % (texturePattern))
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
             loaderOptions = LoaderOptions()
         else:
         else:
             loaderOptions = LoaderOptions(loaderOptions)
             loaderOptions = LoaderOptions(loaderOptions)
@@ -821,13 +824,12 @@ class Loader(DirectObject):
             # callback (passing it the sounds on the parameter list).
             # callback (passing it the sounds on the parameter list).
 
 
             cb = Loader.Callback(len(soundList), gotList, callback, extraArgs)
             cb = Loader.Callback(len(soundList), gotList, callback, extraArgs)
-            for i in range(len(soundList)):
-                soundPath = soundList[i]
+            for i, soundPath in enumerate(soundList):
                 request = AudioLoadRequest(manager, soundPath, positional)
                 request = AudioLoadRequest(manager, soundPath, positional)
                 request.setDoneEvent(self.hook)
                 request.setDoneEvent(self.hook)
-                request.setPythonObject((cb, i))
                 self.loader.loadAsync(request)
                 self.loader.loadAsync(request)
-                cb.requests[request] = True
+                cb.requests.add(request)
+                self.__requests[request] = (cb, i)
             return cb
             return cb
 
 
     def unloadSfx(self, sfx):
     def unloadSfx(self, sfx):
@@ -852,7 +854,7 @@ class Loader(DirectObject):
         return shader
         return shader
 
 
     def unloadShader(self, shaderPath):
     def unloadShader(self, shaderPath):
-        if (shaderPath != None):
+        if shaderPath is not None:
             ShaderPool.releaseShader(shaderPath)
             ShaderPool.releaseShader(shaderPath)
 
 
     def asyncFlattenStrong(self, model, inPlace = True,
     def asyncFlattenStrong(self, model, inPlace = True,
@@ -886,14 +888,15 @@ class Loader(DirectObject):
             gotList = True
             gotList = True
 
 
         cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
         cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
-        i=0
+        i = 0
         for model in modelList:
         for model in modelList:
             request = ModelFlattenRequest(model.node())
             request = ModelFlattenRequest(model.node())
             request.setDoneEvent(self.hook)
             request.setDoneEvent(self.hook)
             request.setPythonObject((cb, i))
             request.setPythonObject((cb, i))
-            i+=1
             self.loader.loadAsync(request)
             self.loader.loadAsync(request)
             cb.requests[request] = True
             cb.requests[request] = True
+            self.__requests[request] = (cb, i)
+            i += 1
         return cb
         return cb
 
 
     def __asyncFlattenDone(self, models,
     def __asyncFlattenDone(self, models,
@@ -921,16 +924,23 @@ class Loader(DirectObject):
         of loaded objects, and call the appropriate callback when it's
         of loaded objects, and call the appropriate callback when it's
         time."""
         time."""
 
 
-        cb, i = request.getPythonObject()
+        if request not in self.__requests:
+            return
+
+        cb, i = self.__requests[request]
         if cb.cancelled:
         if cb.cancelled:
+            # Shouldn't be here.
+            del self.__requests[request]
             return
             return
 
 
-        del cb.requests[request]
+        cb.requests.discard(request)
+        if not cb.requests:
+            del self.__requests[request]
 
 
         object = None
         object = None
         if hasattr(request, "getModel"):
         if hasattr(request, "getModel"):
             node = request.getModel()
             node = request.getModel()
-            if (node != None):
+            if node is not None:
                 object = NodePath(node)
                 object = NodePath(node)
 
 
         elif hasattr(request, "getSound"):
         elif hasattr(request, "getSound"):

+ 4 - 1
direct/src/showutil/FreezeTool.py

@@ -984,7 +984,10 @@ class Freezer:
             try:
             try:
                 self.__loadModule(mdef)
                 self.__loadModule(mdef)
             except ImportError as ex:
             except ImportError as ex:
-                print("Unknown module: %s (%s)" % (mdef.moduleName, str(ex)))
+                message = "Unknown module: %s" % (mdef.moduleName)
+                if str(ex) != "No module named " + str(mdef.moduleName):
+                    message += " (%s)" % (ex)
+                print(message)
 
 
         # Also attempt to import any implicit modules.  If any of
         # Also attempt to import any implicit modules.  If any of
         # these fail to import, we don't really care.
         # these fail to import, we don't really care.

+ 10 - 10
direct/src/stdpy/thread.py

@@ -102,7 +102,7 @@ def start_new_thread(function, args, kwargs = {}, name = None):
             name = 'PythonThread-%s' % (threadId)
             name = 'PythonThread-%s' % (threadId)
 
 
         thread = core.PythonThread(threadFunc, [threadId], name, name)
         thread = core.PythonThread(threadFunc, [threadId], name, name)
-        thread.setPythonData(threadId)
+        thread.setPythonIndex(threadId)
         _threads[threadId] = (thread, {}, None)
         _threads[threadId] = (thread, {}, None)
 
 
         thread.start(core.TPNormal, False)
         thread.start(core.TPNormal, False)
@@ -121,7 +121,7 @@ def _add_thread(thread, wrapper):
         threadId = _nextThreadId
         threadId = _nextThreadId
         _nextThreadId += 1
         _nextThreadId += 1
 
 
-        thread.setPythonData(threadId)
+        thread.setPythonIndex(threadId)
         _threads[threadId] = (thread, {}, wrapper)
         _threads[threadId] = (thread, {}, wrapper)
         return threadId
         return threadId
 
 
@@ -133,8 +133,8 @@ def _get_thread_wrapper(thread, wrapperClass):
     is not one, creates an instance of the indicated wrapperClass
     is not one, creates an instance of the indicated wrapperClass
     instead. """
     instead. """
 
 
-    threadId = thread.getPythonData()
-    if threadId is None:
+    threadId = thread.getPythonIndex()
+    if threadId == -1:
         # The thread has never been assigned a threadId.  Go assign one.
         # The thread has never been assigned a threadId.  Go assign one.
 
 
         global _nextThreadId
         global _nextThreadId
@@ -143,7 +143,7 @@ def _get_thread_wrapper(thread, wrapperClass):
             threadId = _nextThreadId
             threadId = _nextThreadId
             _nextThreadId += 1
             _nextThreadId += 1
 
 
-            thread.setPythonData(threadId)
+            thread.setPythonIndex(threadId)
             wrapper = wrapperClass(thread, threadId)
             wrapper = wrapperClass(thread, threadId)
             _threads[threadId] = (thread, {}, wrapper)
             _threads[threadId] = (thread, {}, wrapper)
             return wrapper
             return wrapper
@@ -169,8 +169,8 @@ def _get_thread_locals(thread, i):
     """ Returns the locals dictionary for the indicated thread.  If
     """ Returns the locals dictionary for the indicated thread.  If
     there is not one, creates an empty dictionary. """
     there is not one, creates an empty dictionary. """
 
 
-    threadId = thread.getPythonData()
-    if threadId is None:
+    threadId = thread.getPythonIndex()
+    if threadId == -1:
         # The thread has never been assigned a threadId.  Go assign one.
         # The thread has never been assigned a threadId.  Go assign one.
 
 
         global _nextThreadId
         global _nextThreadId
@@ -179,7 +179,7 @@ def _get_thread_locals(thread, i):
             threadId = _nextThreadId
             threadId = _nextThreadId
             _nextThreadId += 1
             _nextThreadId += 1
 
 
-            thread.setPythonData(threadId)
+            thread.setPythonIndex(threadId)
             locals = {}
             locals = {}
             _threads[threadId] = (thread, locals, None)
             _threads[threadId] = (thread, locals, None)
             return locals.setdefault(i, {})
             return locals.setdefault(i, {})
@@ -205,9 +205,9 @@ def _remove_thread_id(threadId):
     _threadsLock.acquire()
     _threadsLock.acquire()
     try:
     try:
         thread, locals, wrapper = _threads[threadId]
         thread, locals, wrapper = _threads[threadId]
-        assert thread.getPythonData() == threadId
+        assert thread.getPythonIndex() == threadId
         del _threads[threadId]
         del _threads[threadId]
-        thread.setPythonData(None)
+        thread.setPythonIndex(-1)
 
 
     finally:
     finally:
         _threadsLock.release()
         _threadsLock.release()

+ 10 - 0
doc/ReleaseNotes

@@ -17,6 +17,16 @@ This issue fixes several bugs that were still found in 1.9.2.
 * Improve performance of texture load and store operations
 * Improve performance of texture load and store operations
 * Fix crashes with pbuffers on Intel cards on Windows
 * Fix crashes with pbuffers on Intel cards on Windows
 * Support for Autodesk Maya 2016.5
 * Support for Autodesk Maya 2016.5
+* Add shadow-depth-bits config var to control shadow map depth
+* Fix cull issue when rendering cube map (or any multi-lens setup)
+* Fix crash rendering with the same camera to different contexts
+* Fix compile error when making static build with DX9 renderer
+* Fix assertion when using aux render targets in DX9
+* Work around Cg bug generating invalid ASM for saturated tex loads
+* 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
 
 
 ------------------------  RELEASE 1.9.2  ------------------------
 ------------------------  RELEASE 1.9.2  ------------------------
 
 

+ 0 - 2
dtool/src/cppparser/cppManifest.cxx

@@ -370,10 +370,8 @@ save_expansion(const string &exp, const vector_string &parameter_names) {
 
 
       // Is this identifier one of our parameters?
       // Is this identifier one of our parameters?
       int pnum = -1;
       int pnum = -1;
-      bool va_args = false;
 
 
       if (ident == "__VA_ARGS__") {
       if (ident == "__VA_ARGS__") {
-        va_args = true;
         // C99-style variadics, ie.  #define macro(...) __VA_ARGS__
         // C99-style variadics, ie.  #define macro(...) __VA_ARGS__
         pnum = _variadic_param;
         pnum = _variadic_param;
 
 

+ 3 - 4
dtool/src/cppparser/cppPreprocessor.cxx

@@ -806,7 +806,7 @@ expand_manifests(const string &input_expr, bool expand_undefined,
           Manifests::const_iterator mi = _manifests.find(ident);
           Manifests::const_iterator mi = _manifests.find(ident);
           if (mi != _manifests.end()) {
           if (mi != _manifests.end()) {
             const CPPManifest *manifest = (*mi).second;
             const CPPManifest *manifest = (*mi).second;
-            expand_manifest_inline(expr, q, p, (*mi).second);
+            expand_manifest_inline(expr, q, p, manifest);
             manifest_found = true;
             manifest_found = true;
 
 
           } else if (expand_undefined && ident != "true" && ident != "false") {
           } else if (expand_undefined && ident != "true" && ident != "false") {
@@ -1192,8 +1192,6 @@ skip_c_comment(int c) {
 
 
   } else {
   } else {
     CPPFile first_file = get_file();
     CPPFile first_file = get_file();
-    int first_line_number = get_line_number();
-    int first_col_number = get_col_number() - 2;
 
 
     while (c != EOF) {
     while (c != EOF) {
       if (c == '*') {
       if (c == '*') {
@@ -1816,8 +1814,9 @@ get_identifier(int c) {
       type = CPPExpression::T_u16string;
       type = CPPExpression::T_u16string;
     } else if (name == "U") {
     } else if (name == "U") {
       type = CPPExpression::T_u32string;
       type = CPPExpression::T_u32string;
+    } else {
+      type = CPPExpression::T_string;
     }
     }
-
     get();
     get();
     string str = scan_quoted(c);
     string str = scan_quoted(c);
 
 

+ 1 - 1
dtool/src/cppparser/cppToken.cxx

@@ -40,7 +40,7 @@ CPPToken(int token, int line_number, int col_number,
  */
  */
 CPPToken::
 CPPToken::
 CPPToken(int token, const YYLTYPE &loc, const string &str, const YYSTYPE &val) :
 CPPToken(int token, const YYLTYPE &loc, const string &str, const YYSTYPE &val) :
-  _token(token), _lloc(loc), _lval(val)
+  _token(token), _lval(val), _lloc(loc)
 {
 {
   _lval.str = str;
   _lval.str = str;
 }
 }

+ 11 - 9
dtool/src/dtoolbase/dtoolbase.h

@@ -70,23 +70,25 @@
 #else
 #else
 // #pragma message("VC 6.0")
 // #pragma message("VC 6.0")
 #endif
 #endif
+#endif  /* WIN32_VC */
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
 
 
 // Use NODEFAULT to optimize a switch() stmt to tell MSVC to automatically go
 // Use NODEFAULT to optimize a switch() stmt to tell MSVC to automatically go
 // to the final untested case after it has failed all the other cases (i.e.
 // to the final untested case after it has failed all the other cases (i.e.
 // 'assume at least one of the cases is always true')
 // 'assume at least one of the cases is always true')
 #ifdef _DEBUG
 #ifdef _DEBUG
-# define NODEFAULT  default: assert(0);
+#define NODEFAULT  default: assert(0); break;
+#elif defined(_MSC_VER)
+#define NODEFAULT  default: __assume(0);   // special VC keyword
+#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || __has_builtin(__builtin_unreachable)
+#define NODEFAULT  default: __builtin_unreachable();
 #else
 #else
-# define NODEFAULT  default: __assume(0);   // special VC keyword
+#define NODEFAULT
 #endif
 #endif
 
 
-#else /* if !WIN32_VC */
-#ifdef _DEBUG
-# define NODEFAULT   default: assert(0);
-#else
-# define NODEFAULT
-#endif
-#endif  /* WIN32_VC */
 
 
 /*
 /*
   include win32 defns for everything up to WinServer2003, and assume
   include win32 defns for everything up to WinServer2003, and assume

+ 6 - 0
dtool/src/dtoolbase/typeRegistry.cxx

@@ -341,6 +341,8 @@ get_root_class(int n) {
   TypeHandle handle;
   TypeHandle handle;
   if (n >= 0 && n < (int)_root_classes.size()) {
   if (n >= 0 && n < (int)_root_classes.size()) {
     handle = _root_classes[n]->_handle;
     handle = _root_classes[n]->_handle;
+  } else {
+    handle = TypeHandle::none();
   }
   }
   _lock->release();
   _lock->release();
 
 
@@ -380,6 +382,8 @@ get_parent_class(TypeHandle child, int index) const {
   assert(rnode != (TypeRegistryNode *)NULL);
   assert(rnode != (TypeRegistryNode *)NULL);
   if (index >= 0 && index < (int)rnode->_parent_classes.size()) {
   if (index >= 0 && index < (int)rnode->_parent_classes.size()) {
     handle = rnode->_parent_classes[index]->_handle;
     handle = rnode->_parent_classes[index]->_handle;
+  } else {
+    handle = TypeHandle::none();
   }
   }
   _lock->release();
   _lock->release();
   return handle;
   return handle;
@@ -415,6 +419,8 @@ get_child_class(TypeHandle child, int index) const {
   assert(rnode != (TypeRegistryNode *)NULL);
   assert(rnode != (TypeRegistryNode *)NULL);
   if (index >= 0 && index < (int)rnode->_child_classes.size()) {
   if (index >= 0 && index < (int)rnode->_child_classes.size()) {
     handle = rnode->_child_classes[index]->_handle;
     handle = rnode->_child_classes[index]->_handle;
+  } else {
+    handle = TypeHandle::none();
   }
   }
   _lock->release();
   _lock->release();
   return handle;
   return handle;

+ 1 - 1
dtool/src/dtoolutil/pandaFileStreamBuf.cxx

@@ -323,7 +323,7 @@ seekoff(streamoff off, ios_seekdir dir, ios_openmode which) {
       // Posix case.
       // Posix case.
       {
       {
         off_t li = lseek(_fd, off, SEEK_END);
         off_t li = lseek(_fd, off, SEEK_END);
-        if (li == (size_t)-1) {
+        if (li == (off_t)-1) {
           return -1;
           return -1;
         }
         }
         new_pos = (size_t)li;
         new_pos = (size_t)li;

+ 49 - 5
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -1259,9 +1259,16 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
       if (is_cpp_type_legal(object->_itype._cpptype) &&
       if (is_cpp_type_legal(object->_itype._cpptype) &&
           isExportThisRun(object->_itype._cpptype)) {
           isExportThisRun(object->_itype._cpptype)) {
         string class_name = make_safe_name(object->_itype.get_scoped_name());
         string class_name = make_safe_name(object->_itype.get_scoped_name());
-        bool is_typed = HasAGetClassTypeFunction(object->_itype._cpptype);
+        bool is_typed = has_get_class_type_function(object->_itype._cpptype);
 
 
         if (is_typed) {
         if (is_typed) {
+          if (has_init_type_function(object->_itype._cpptype)) {
+            // Call the init_type function.  This isn't necessary for all
+            // types as many of them are automatically initialized at static
+            // init type, but for some extension classes it's useful.
+            out << "  " << object->_itype._cpptype->get_local_name(&parser)
+                << "::init_type();\n";
+          }
           out << "  Dtool_" << class_name << "._type = "
           out << "  Dtool_" << class_name << "._type = "
               << object->_itype._cpptype->get_local_name(&parser)
               << object->_itype._cpptype->get_local_name(&parser)
               << "::get_class_type();\n"
               << "::get_class_type();\n"
@@ -1291,7 +1298,7 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
     string class_name = (*ii)->get_local_name(&parser);
     string class_name = (*ii)->get_local_name(&parser);
     string safe_name = make_safe_name(class_name);
     string safe_name = make_safe_name(class_name);
 
 
-    if (HasAGetClassTypeFunction(*ii)) {
+    if (has_get_class_type_function(*ii)) {
       out << "  Dtool_Ptr_" << safe_name << " = LookupRuntimeTypedClass(" << class_name << "::get_class_type());\n";
       out << "  Dtool_Ptr_" << safe_name << " = LookupRuntimeTypedClass(" << class_name << "::get_class_type());\n";
     } else {
     } else {
       out << "  Dtool_Ptr_" << safe_name << " = LookupNamedClass(\"" << class_name << "\");\n";
       out << "  Dtool_Ptr_" << safe_name << " = LookupNamedClass(\"" << class_name << "\");\n";
@@ -1541,7 +1548,7 @@ write_module_class(ostream &out, Object *obj) {
   std::string export_class_name = classNameFromCppName(obj->_itype.get_name(), false);
   std::string export_class_name = classNameFromCppName(obj->_itype.get_name(), false);
 
 
   bool is_runtime_typed = IsPandaTypedObject(obj->_itype._cpptype->as_struct_type());
   bool is_runtime_typed = IsPandaTypedObject(obj->_itype._cpptype->as_struct_type());
-  if (!is_runtime_typed && HasAGetClassTypeFunction(obj->_itype._cpptype)) {
+  if (!is_runtime_typed && has_get_class_type_function(obj->_itype._cpptype)) {
     is_runtime_typed = true;
     is_runtime_typed = true;
   }
   }
 
 
@@ -4196,7 +4203,7 @@ write_function_forset(ostream &out,
     return;
     return;
   }
   }
 
 
-  FunctionRemap *remap;
+  FunctionRemap *remap = NULL;
   std::set<FunctionRemap *>::iterator sii;
   std::set<FunctionRemap *>::iterator sii;
 
 
   bool all_nonconst = false;
   bool all_nonconst = false;
@@ -7010,7 +7017,7 @@ DoesInheritFromIsClass(const CPPStructType *inclass, const std::string &name) {
 
 
  */
  */
 bool InterfaceMakerPythonNative::
 bool InterfaceMakerPythonNative::
-HasAGetClassTypeFunction(CPPType *type) {
+has_get_class_type_function(CPPType *type) {
   while (type->get_subtype() == CPPDeclaration::ST_typedef) {
   while (type->get_subtype() == CPPDeclaration::ST_typedef) {
     type = type->as_typedef_type()->_type;
     type = type->as_typedef_type()->_type;
   }
   }
@@ -7025,6 +7032,43 @@ HasAGetClassTypeFunction(CPPType *type) {
   return scope->_functions.find("get_class_type") != scope->_functions.end();
   return scope->_functions.find("get_class_type") != scope->_functions.end();
 }
 }
 
 
+/**
+ *
+ */
+bool InterfaceMakerPythonNative::
+has_init_type_function(CPPType *type) {
+  while (type->get_subtype() == CPPDeclaration::ST_typedef) {
+    type = type->as_typedef_type()->_type;
+  }
+
+  CPPStructType *struct_type = type->as_struct_type();
+  if (struct_type == NULL) {
+    return false;
+  }
+
+  CPPScope *scope = struct_type->get_scope();
+  CPPScope::Functions::const_iterator it = scope->_functions.find("init_type");
+  if (it == scope->_functions.end()) {
+    return false;
+  }
+  const CPPFunctionGroup *group = it->second;
+
+  CPPFunctionGroup::Instances::const_iterator ii;
+  for (ii = group->_instances.begin(); ii != group->_instances.end(); ++ii) {
+    const CPPInstance *cppinst = *ii;
+    const CPPFunctionType *cppfunc = cppinst->_type->as_function_type();
+
+    if (cppfunc != NULL &&
+        cppfunc->_parameters != NULL &&
+        cppfunc->_parameters->_parameters.size() == 0 &&
+        (cppinst->_storage_class & CPPInstance::SC_static) != 0) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 /**
 /**
  * Returns -1 if the class does not define write() (and therefore cannot
  * Returns -1 if the class does not define write() (and therefore cannot
  * support a __str__ function).
  * support a __str__ function).

+ 2 - 1
dtool/src/interrogate/interfaceMakerPythonNative.h

@@ -201,7 +201,8 @@ public:
   bool DoesInheritFromIsClass(const CPPStructType * inclass, const std::string &name);
   bool DoesInheritFromIsClass(const CPPStructType * inclass, const std::string &name);
   bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); };
   bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); };
   void write_python_instance(ostream &out, int indent_level, const std::string &return_expr, bool owns_memory, const InterrogateType &itype, bool is_const);
   void write_python_instance(ostream &out, int indent_level, const std::string &return_expr, bool owns_memory, const InterrogateType &itype, bool is_const);
-  bool HasAGetClassTypeFunction(CPPType *type);
+  bool has_get_class_type_function(CPPType *type);
+  bool has_init_type_function(CPPType *type);
   int NeedsAStrFunction(const InterrogateType &itype_class);
   int NeedsAStrFunction(const InterrogateType &itype_class);
   int NeedsAReprFunction(const InterrogateType &itype_class);
   int NeedsAReprFunction(const InterrogateType &itype_class);
   bool NeedsARichCompareFunction(const InterrogateType &itype_class);
   bool NeedsARichCompareFunction(const InterrogateType &itype_class);

+ 0 - 4
dtool/src/interrogate/interrogate.cxx

@@ -19,7 +19,6 @@
 #include "pnotify.h"
 #include "pnotify.h"
 #include "panda_getopt_long.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
 #include "preprocess_argv.h"
-#include "pystub.h"
 #include <time.h>
 #include <time.h>
 
 
 CPPParser parser;
 CPPParser parser;
@@ -306,9 +305,6 @@ predefine_macro(CPPParser& parser, const string& inoption) {
 
 
 int
 int
 main(int argc, char **argv) {
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   preprocess_argv(argc, argv);
   preprocess_argv(argc, argv);
   string command_line;
   string command_line;
   int i;
   int i;

+ 4 - 4
dtool/src/interrogate/interrogateBuilder.cxx

@@ -1851,9 +1851,9 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type, CP
       }
       }
 
 
       // The getter must either take no arguments, or all defaults.
       // The getter must either take no arguments, or all defaults.
-      if (ftype->_parameters->_parameters.size() == (int)is_seq ||
-          (ftype->_parameters->_parameters.size() > (int)is_seq &&
-           ftype->_parameters->_parameters[(int)is_seq]->_initializer != NULL)) {
+      if (ftype->_parameters->_parameters.size() == (size_t)is_seq ||
+          (ftype->_parameters->_parameters.size() > (size_t)is_seq &&
+           ftype->_parameters->_parameters[(size_t)is_seq]->_initializer != NULL)) {
         // If this is a sequence getter, it must take an index argument.
         // If this is a sequence getter, it must take an index argument.
         if (is_seq && !TypeManager::is_integer(ftype->_parameters->_parameters[0]->_type)) {
         if (is_seq && !TypeManager::is_integer(ftype->_parameters->_parameters[0]->_type)) {
           continue;
           continue;
@@ -1909,7 +1909,7 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type, CP
     for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
     for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
       CPPInstance *function = (*fi);
       CPPInstance *function = (*fi);
       CPPFunctionType *ftype = function->_type->as_function_type();
       CPPFunctionType *ftype = function->_type->as_function_type();
-      if (ftype != NULL && ftype->_parameters->_parameters.size() == (int)is_seq) {
+      if (ftype != NULL && ftype->_parameters->_parameters.size() == (size_t)is_seq) {
         deleter = function;
         deleter = function;
         break;
         break;
       }
       }

+ 0 - 4
dtool/src/interrogate/interrogate_module.cxx

@@ -19,7 +19,6 @@
 #include "interrogate_interface.h"
 #include "interrogate_interface.h"
 #include "interrogate_request.h"
 #include "interrogate_request.h"
 #include "load_dso.h"
 #include "load_dso.h"
-#include "pystub.h"
 #include "pnotify.h"
 #include "pnotify.h"
 #include "panda_getopt_long.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
 #include "preprocess_argv.h"
@@ -380,9 +379,6 @@ int main(int argc, char *argv[]) {
   extern int optind;
   extern int optind;
   int flag;
   int flag;
 
 
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   preprocess_argv(argc, argv);
   preprocess_argv(argc, argv);
   flag = getopt_long_only(argc, argv, short_options, long_options, NULL);
   flag = getopt_long_only(argc, argv, short_options, long_options, NULL);
   while (flag != EOF) {
   while (flag != EOF) {

+ 1 - 1
dtool/src/interrogate/typeManager.cxx

@@ -41,7 +41,7 @@ resolve_type(CPPType *type, CPPScope *scope) {
     scope = &parser;
     scope = &parser;
   }
   }
 
 
-  CPPType *orig_type = type;
+  //CPPType *orig_type = type;
   type = type->resolve_type(scope, &parser);
   type = type->resolve_type(scope, &parser);
   string name = type->get_local_name(&parser);
   string name = type->get_local_name(&parser);
   if (name.empty()) {
   if (name.empty()) {

+ 1 - 1
dtool/src/interrogatedb/extension.h

@@ -31,7 +31,7 @@ public:
  * extended should create a specialization of this class template.
  * extended should create a specialization of this class template.
  */
  */
 template<class T>
 template<class T>
-class EXPCL_INTERROGATEDB Extension : public ExtensionBase<T> {
+class Extension : public ExtensionBase<T> {
 };
 };
 
 
 /**
 /**

+ 8 - 0
dtool/src/interrogatedb/py_panda.I

@@ -107,7 +107,15 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(long long value) {
 }
 }
 
 
 ALWAYS_INLINE PyObject *Dtool_WrapValue(unsigned long long value) {
 ALWAYS_INLINE PyObject *Dtool_WrapValue(unsigned long long value) {
+  // size_t is sometimes defined as unsigned long long, and we want to map
+  // that to int in Python 2 so it can be returned from a __len__.
+#if PY_MAJOR_VERSION >= 3
   return PyLong_FromUnsignedLongLong(value);
   return PyLong_FromUnsignedLongLong(value);
+#else
+  return (value > LONG_MAX)
+    ? PyLong_FromUnsignedLongLong(value)
+    : PyInt_FromLong((long)value);
+#endif
 }
 }
 
 
 ALWAYS_INLINE PyObject *Dtool_WrapValue(bool value) {
 ALWAYS_INLINE PyObject *Dtool_WrapValue(bool value) {

+ 2 - 0
dtool/src/interrogatedb/py_panda.cxx

@@ -816,6 +816,7 @@ PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op) {
   int cmpval = DTOOL_PyObject_Compare(v1, v2);
   int cmpval = DTOOL_PyObject_Compare(v1, v2);
   bool result;
   bool result;
   switch (op) {
   switch (op) {
+  NODEFAULT
   case Py_LT:
   case Py_LT:
     result = (cmpval < 0);
     result = (cmpval < 0);
     break;
     break;
@@ -833,6 +834,7 @@ PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op) {
     break;
     break;
   case Py_GE:
   case Py_GE:
     result = (cmpval >= 0);
     result = (cmpval >= 0);
+    break;
   }
   }
   return PyBool_FromLong(result);
   return PyBool_FromLong(result);
 }
 }

+ 4 - 3
dtool/src/interrogatedb/py_panda.h

@@ -219,9 +219,10 @@ static PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyOb
 }
 }
 
 
 // The following used to be in the above macro, but it doesn't seem to be
 // The following used to be in the above macro, but it doesn't seem to be
-// necessary as tp_alloc memsets the object to 0. ((Dtool_PyInstDef
-// *)self)->_ptr_to_object = NULL;\ ((Dtool_PyInstDef *)self)->_memory_rules =
-// false;\ ((Dtool_PyInstDef *)self)->_is_const = false;\
+// necessary as tp_alloc memsets the object to 0.
+//  ((Dtool_PyInstDef *)self)->_ptr_to_object = NULL;
+//  ((Dtool_PyInstDef *)self)->_memory_rules = false;
+//  ((Dtool_PyInstDef *)self)->_is_const = false;
 
 
 // Delete functions..
 // Delete functions..
 #ifdef NDEBUG
 #ifdef NDEBUG

+ 1 - 1
dtool/src/parser-inc/Python.h

@@ -30,7 +30,7 @@ typedef struct {} PyUnicodeObject;
 
 
 class PyThreadState;
 class PyThreadState;
 typedef int Py_ssize_t;
 typedef int Py_ssize_t;
-struct Py_buffer;
+typedef struct bufferinfo Py_buffer;
 
 
 // We need to define these accurately since interrogate may want to
 // We need to define these accurately since interrogate may want to
 // write these out to default value assignments.
 // write these out to default value assignments.

+ 21 - 9
dtool/src/prc/configVariableFilename.cxx

@@ -19,16 +19,28 @@
  */
  */
 void ConfigVariableFilename::
 void ConfigVariableFilename::
 reload_cache() {
 reload_cache() {
-  nassertv(_core != (ConfigVariableCore *)NULL);
-  mark_cache_valid(_local_modified);
+  // NB. MSVC doesn't guarantee that this mutex is initialized in a
+  // thread-safe manner.  But chances are that the first time this is called
+  // is at static init time, when there is no risk of data races.
+  static MutexImpl lock;
+  lock.acquire();
 
 
-  const ConfigDeclaration *decl = _core->get_declaration(0);
-  const ConfigPage *page = decl->get_page();
+  // We check again for cache validity since another thread may have beaten
+  // us to the punch while we were waiting for the lock.
+  if (!is_cache_valid(_local_modified)) {
+    nassertv(_core != (ConfigVariableCore *)NULL);
 
 
-  Filename page_filename(page->get_name());
-  Filename page_dirname = page_filename.get_dirname();
-  ExecutionEnvironment::shadow_environment_variable("THIS_PRC_DIR", page_dirname.to_os_specific());
+    const ConfigDeclaration *decl = _core->get_declaration(0);
+    const ConfigPage *page = decl->get_page();
 
 
-  _cache = Filename::expand_from(decl->get_string_value());
-  ExecutionEnvironment::clear_shadow("THIS_PRC_DIR");
+    Filename page_filename(page->get_name());
+    Filename page_dirname = page_filename.get_dirname();
+    ExecutionEnvironment::shadow_environment_variable("THIS_PRC_DIR", page_dirname.to_os_specific());
+
+    _cache = Filename::expand_from(decl->get_string_value());
+    ExecutionEnvironment::clear_shadow("THIS_PRC_DIR");
+
+    mark_cache_valid(_local_modified);
+  }
+  lock.release();
 }
 }

+ 1 - 2
dtool/src/prc/configVariableString.I

@@ -127,8 +127,7 @@ INLINE const string &ConfigVariableString::
 get_value() const {
 get_value() const {
   TAU_PROFILE("const string &ConfigVariableString::get_value() const", " ", TAU_USER);
   TAU_PROFILE("const string &ConfigVariableString::get_value() const", " ", TAU_USER);
   if (!is_cache_valid(_local_modified)) {
   if (!is_cache_valid(_local_modified)) {
-    mark_cache_valid(((ConfigVariableString *)this)->_local_modified);
-    ((ConfigVariableString *)this)->_cache = get_string_value();
+    ((ConfigVariableString *)this)->reload_cache();
   }
   }
   return _cache;
   return _cache;
 }
 }

+ 21 - 0
dtool/src/prc/configVariableString.cxx

@@ -12,3 +12,24 @@
  */
  */
 
 
 #include "configVariableString.h"
 #include "configVariableString.h"
+
+/**
+ * Refreshes the variable's cached value.
+ */
+void ConfigVariableString::
+reload_cache() {
+  // NB. MSVC doesn't guarantee that this mutex is initialized in a
+  // thread-safe manner.  But chances are that the first time this is called
+  // is at static init time, when there is no risk of data races.
+  static MutexImpl lock;
+  lock.acquire();
+
+  // We check again for cache validity since another thread may have beaten
+  // us to the punch while we were waiting for the lock.
+  if (!is_cache_valid(_local_modified)) {
+    _cache = get_string_value();
+    mark_cache_valid(_local_modified);
+  }
+
+  lock.release();
+}

+ 3 - 0
dtool/src/prc/configVariableString.h

@@ -49,6 +49,9 @@ PUBLISHED:
   INLINE string get_word(size_t n) const;
   INLINE string get_word(size_t n) const;
   INLINE void set_word(size_t n, const string &value);
   INLINE void set_word(size_t n, const string &value);
 
 
+private:
+  void reload_cache();
+
 private:
 private:
   AtomicAdjust::Integer _local_modified;
   AtomicAdjust::Integer _local_modified;
   string _cache;
   string _cache;

+ 0 - 1
dtool/src/test_interrogate/test_interrogate.cxx

@@ -17,7 +17,6 @@
 #include "interrogate_request.h"
 #include "interrogate_request.h"
 #include "load_dso.h"
 #include "load_dso.h"
 #include "filename.h"
 #include "filename.h"
-#include "pystub.h"
 #include "panda_getopt.h"
 #include "panda_getopt.h"
 #include "preprocess_argv.h"
 #include "preprocess_argv.h"
 
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 136 - 126
makepanda/makepanda.py


+ 0 - 4
panda/src/android/pview.cxx

@@ -13,7 +13,6 @@
 
 
 #include "pandaFramework.h"
 #include "pandaFramework.h"
 #include "pandaSystem.h"
 #include "pandaSystem.h"
-#include "pystub.h"
 #include "texturePool.h"
 #include "texturePool.h"
 #include "multitexReducer.h"
 #include "multitexReducer.h"
 #include "sceneGraphReducer.h"
 #include "sceneGraphReducer.h"
@@ -29,9 +28,6 @@
 #include "checkPandaVersion.h"
 #include "checkPandaVersion.h"
 
 
 int main(int argc, char **argv) {
 int main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   PandaFramework framework;
   PandaFramework framework;
   framework.open_framework(argc, argv);
   framework.open_framework(argc, argv);
   framework.set_window_title("Panda Viewer");
   framework.set_window_title("Panda Viewer");

+ 17 - 0
panda/src/chan/animChannelFixed.cxx

@@ -0,0 +1,17 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file animChannelFixed.cxx
+ * @author rdb
+ * @date 2016-05-29
+ */
+
+#include "animChannelFixed.h"
+
+template class AnimChannelFixed<ACMatrixSwitchType>;
+template class AnimChannelFixed<ACScalarSwitchType>;

+ 2 - 0
panda/src/chan/animChannelFixed.h

@@ -62,6 +62,8 @@ private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;
 };
 };
 
 
+EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_CHAN, EXPTP_PANDA_CHAN, AnimChannelFixed<ACMatrixSwitchType>);
+EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_CHAN, EXPTP_PANDA_CHAN, AnimChannelFixed<ACScalarSwitchType>);
 
 
 #include "animChannelFixed.I"
 #include "animChannelFixed.I"
 
 

+ 1 - 0
panda/src/chan/p3chan_composite1.cxx

@@ -3,6 +3,7 @@
 #include "animBundleNode.cxx"
 #include "animBundleNode.cxx"
 #include "animChannel.cxx"
 #include "animChannel.cxx"
 #include "animChannelBase.cxx"
 #include "animChannelBase.cxx"
+#include "animChannelFixed.cxx"
 #include "animChannelMatrixDynamic.cxx"
 #include "animChannelMatrixDynamic.cxx"
 #include "animChannelMatrixFixed.cxx"
 #include "animChannelMatrixFixed.cxx"
 #include "animChannelMatrixXfmTable.cxx"
 #include "animChannelMatrixXfmTable.cxx"

+ 1 - 1
panda/src/char/character.cxx

@@ -228,7 +228,7 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool &found_any,
   // around this, we will force-recompute all of the bounding volumes of our
   // around this, we will force-recompute all of the bounding volumes of our
   // parent nodes immediately.
   // parent nodes immediately.
   Parents parents = get_parents();
   Parents parents = get_parents();
-  for (int i = 0; i < parents.get_num_parents(); ++i) {
+  for (size_t i = 0; i < parents.get_num_parents(); ++i) {
     PandaNode *parent = parents.get_parent(i);
     PandaNode *parent = parents.get_parent(i);
     parent->get_bounds();
     parent->get_bounds();
   }
   }

+ 0 - 3
panda/src/display/displayRegion.cxx

@@ -638,9 +638,6 @@ do_compute_pixels(int i, int x_size, int y_size, CData *cdata) {
 
 
   Region &region = cdata->_regions[i];
   Region &region = cdata->_regions[i];
 
 
-  int old_w = region._pixels[1] - region._pixels[0];
-  int old_h = region._pixels[3] - region._pixels[2];
-
   region._pixels[0] = int((region._dimensions[0] * x_size) + 0.5);
   region._pixels[0] = int((region._dimensions[0] * x_size) + 0.5);
   region._pixels[1] = int((region._dimensions[1] * x_size) + 0.5);
   region._pixels[1] = int((region._dimensions[1] * x_size) + 0.5);
   region._pixels_i[0] = region._pixels[0];
   region._pixels_i[0] = region._pixels[0];

+ 27 - 8
panda/src/display/graphicsEngine.cxx

@@ -118,6 +118,23 @@ PStatCollector GraphicsEngine::_occlusion_passed_pcollector("Occlusion results:V
 PStatCollector GraphicsEngine::_occlusion_failed_pcollector("Occlusion results:Occluded");
 PStatCollector GraphicsEngine::_occlusion_failed_pcollector("Occlusion results:Occluded");
 PStatCollector GraphicsEngine::_occlusion_tests_pcollector("Occlusion tests");
 PStatCollector GraphicsEngine::_occlusion_tests_pcollector("Occlusion tests");
 
 
+// This is used to keep track of which scenes we have already culled.
+struct CullKey {
+  GraphicsStateGuardian *_gsg;
+  NodePath _camera;
+  int _lens_index;
+};
+
+INLINE static bool operator < (const CullKey &a, const CullKey &b) {
+  if (a._gsg != b._gsg) {
+    return a._gsg < b._gsg;
+  }
+  if (a._camera != b._camera) {
+    return a._camera < b._camera;
+  }
+  return a._lens_index < b._lens_index;
+}
+
 /**
 /**
  * Creates a new GraphicsEngine object.  The Pipeline is normally left to
  * Creates a new GraphicsEngine object.  The Pipeline is normally left to
  * default to NULL, which indicates the global render pipeline, but it may be
  * default to NULL, which indicates the global render pipeline, but it may be
@@ -1375,7 +1392,6 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
 
 
   // Keep track of the cameras we have already used in this thread to render
   // Keep track of the cameras we have already used in this thread to render
   // DisplayRegions.
   // DisplayRegions.
-  typedef pair<NodePath, int> CullKey;
   typedef pmap<CullKey, DisplayRegion *> AlreadyCulled;
   typedef pmap<CullKey, DisplayRegion *> AlreadyCulled;
   AlreadyCulled already_culled;
   AlreadyCulled already_culled;
 
 
@@ -1390,10 +1406,13 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
         if (dr != (DisplayRegion *)NULL) {
         if (dr != (DisplayRegion *)NULL) {
           DisplayRegionPipelineReader *dr_reader =
           DisplayRegionPipelineReader *dr_reader =
             new DisplayRegionPipelineReader(dr, current_thread);
             new DisplayRegionPipelineReader(dr, current_thread);
-          NodePath camera = dr_reader->get_camera();
-          int lens_index = dr_reader->get_lens_index();
 
 
-          AlreadyCulled::iterator aci = already_culled.insert(AlreadyCulled::value_type(CullKey(camera, lens_index), (DisplayRegion *)NULL)).first;
+          CullKey key;
+          key._gsg = win->get_gsg();
+          key._camera = dr_reader->get_camera();
+          key._lens_index = dr_reader->get_lens_index();
+
+          AlreadyCulled::iterator aci = already_culled.insert(AlreadyCulled::value_type(key, (DisplayRegion *)NULL)).first;
           if ((*aci).second == NULL) {
           if ((*aci).second == NULL) {
             // We have not used this camera already in this thread.  Perform
             // We have not used this camera already in this thread.  Perform
             // the cull operation.
             // the cull operation.
@@ -1508,7 +1527,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
         // We have to place this collector inside begin_frame, because we need
         // We have to place this collector inside begin_frame, because we need
         // a current context for PStatGPUTimer to work.
         // a current context for PStatGPUTimer to work.
         {
         {
-          PStatGPUTimer timer(win->get_gsg(), win->get_draw_window_pcollector(), current_thread);
+          PStatGPUTimer timer(gsg, win->get_draw_window_pcollector(), current_thread);
           win->clear(current_thread);
           win->clear(current_thread);
 
 
           if (display_cat.is_spam()) {
           if (display_cat.is_spam()) {
@@ -1528,8 +1547,8 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
         if (_auto_flip) {
         if (_auto_flip) {
 #ifdef DO_PSTATS
 #ifdef DO_PSTATS
           // This is a good time to perform a latency query.
           // This is a good time to perform a latency query.
-          if (win->get_gsg()->get_timer_queries_active()) {
-            win->get_gsg()->issue_timer_query(GraphicsStateGuardian::_command_latency_pcollector.get_index());
+          if (gsg->get_timer_queries_active()) {
+            gsg->issue_timer_query(GraphicsStateGuardian::_command_latency_pcollector.get_index());
           }
           }
 #endif
 #endif
 
 
@@ -1541,7 +1560,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
               win->begin_flip();
               win->begin_flip();
             }
             }
             {
             {
-              PStatGPUTimer timer(win->get_gsg(), GraphicsEngine::_flip_end_pcollector, current_thread);
+              PStatGPUTimer timer(gsg, GraphicsEngine::_flip_end_pcollector, current_thread);
               win->end_flip();
               win->end_flip();
             }
             }
           }
           }

+ 2 - 0
panda/src/display/graphicsPipeSelection.cxx

@@ -105,6 +105,8 @@ get_pipe_type(int n) const {
     LightMutexHolder holder(_lock);
     LightMutexHolder holder(_lock);
     if (n >= 0 && n < (int)_pipe_types.size()) {
     if (n >= 0 && n < (int)_pipe_types.size()) {
       result = _pipe_types[n]._type;
       result = _pipe_types[n]._type;
+    } else {
+      result = TypeHandle::none();
     }
     }
   }
   }
   return result;
   return result;

+ 1 - 2
panda/src/display/graphicsStateGuardian.cxx

@@ -238,6 +238,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
   _supports_basic_shaders = false;
   _supports_basic_shaders = false;
   _supports_geometry_shaders = false;
   _supports_geometry_shaders = false;
   _supports_tessellation_shaders = false;
   _supports_tessellation_shaders = false;
+  _supports_compute_shaders = false;
   _supports_glsl = false;
   _supports_glsl = false;
   _supports_hlsl = false;
   _supports_hlsl = false;
   _supports_framebuffer_multisample = false;
   _supports_framebuffer_multisample = false;
@@ -2065,8 +2066,6 @@ flush_timer_queries() {
 
 
     _last_num_queried = first;
     _last_num_queried = first;
 
 
-    int frame_index = ClockObject::get_global_clock()->get_frame_count();
-
     for (int i = 0; i < first; ++i) {
     for (int i = 0; i < first; ++i) {
       CPT(TimerQueryContext) query = _pending_timer_queries[i];
       CPT(TimerQueryContext) query = _pending_timer_queries[i];
 
 

+ 0 - 10
panda/src/display/standardMunger.I

@@ -18,13 +18,3 @@ INLINE GraphicsStateGuardian *StandardMunger::
 get_gsg() const {
 get_gsg() const {
   return (GraphicsStateGuardian *)GeomMunger::get_gsg();
   return (GraphicsStateGuardian *)GeomMunger::get_gsg();
 }
 }
-
-/**
- * Returns the render mode active on this munger.  Intended for derived
- * classes that may have to munge differently depending on render mode.
- */
-INLINE RenderModeAttrib::Mode StandardMunger::
-get_render_mode() const {
-  return (_render_mode != NULL) ? _render_mode->get_mode()
-                                : RenderModeAttrib::M_filled;
-}

+ 16 - 23
panda/src/display/standardMunger.cxx

@@ -38,9 +38,6 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
   _auto_shader(false),
   _auto_shader(false),
   _shader_skinning(false)
   _shader_skinning(false)
 {
 {
-  _render_mode = (const RenderModeAttrib *)
-    state->get_attrib(RenderModeAttrib::get_class_slot());
-
   if (!get_gsg()->get_runtime_color_scale()) {
   if (!get_gsg()->get_runtime_color_scale()) {
     // We might need to munge the colors.
     // We might need to munge the colors.
     const ColorAttrib *color_attrib;
     const ColorAttrib *color_attrib;
@@ -183,14 +180,14 @@ munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data,
     // it rather than draw them one by one.
     // it rather than draw them one by one.
     if ((unsupported_bits & Geom::GR_composite_bits) != 0 ||
     if ((unsupported_bits & Geom::GR_composite_bits) != 0 ||
         (unsupported_bits & Geom::GR_strip_cut_index) != 0) {
         (unsupported_bits & Geom::GR_strip_cut_index) != 0) {
-/*
- * This decomposes everything in the primitive, so that if (for instance) the
- * primitive contained both strips and fans, but the GSG didn't support fans,
- * it would decompose the strips too.  To handle this correctly, we'd need a
- * separate decompose_fans() and decompose_strips() call; but for now, we'll
- * just say it's good enough.  In practice, we don't have any GSG's that can
- * support strips without also supporting fans.
- */
+
+      // This decomposes everything in the primitive, so that if (for
+      // instance) the primitive contained both strips and fans, but the GSG
+      // didn't support fans, it would decompose the strips too.  To handle
+      // this correctly, we'd need a separate decompose_fans() and
+      // decompose_strips() call; but for now, we'll just say it's good
+      // enough.  In practice, we don't have any GSG's that can support strips
+      // without also supporting fans.
       geom = geom->decompose();
       geom = geom->decompose();
 
 
       // Decomposing might produce an indexed Geom, so re-check the
       // Decomposing might produce an indexed Geom, so re-check the
@@ -228,14 +225,14 @@ premunge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data) {
     // it rather than draw them one by one.
     // it rather than draw them one by one.
     if ((unsupported_bits & Geom::GR_composite_bits) != 0 ||
     if ((unsupported_bits & Geom::GR_composite_bits) != 0 ||
         (unsupported_bits & Geom::GR_strip_cut_index) != 0) {
         (unsupported_bits & Geom::GR_strip_cut_index) != 0) {
-/*
- * This decomposes everything in the primitive, so that if (for instance) the
- * primitive contained both strips and fans, but the GSG didn't support fans,
- * it would decompose the strips too.  To handle this correctly, we'd need a
- * separate decompose_fans() and decompose_strips() call; but for now, we'll
- * just say it's good enough.  In practice, we don't have any GSG's that can
- * support strips without also supporting fans.
- */
+
+      // This decomposes everything in the primitive, so that if (for
+      // instance) the primitive contained both strips and fans, but the GSG
+      // didn't support fans, it would decompose the strips too.  To handle
+      // this correctly, we'd need a separate decompose_fans() and
+      // decompose_strips() call; but for now, we'll just say it's good
+      // enough.  In practice, we don't have any GSG's that can support strips
+      // without also supporting fans.
       geom = geom->decompose();
       geom = geom->decompose();
 
 
       // Decomposing might produce an indexed Geom, so re-check the
       // Decomposing might produce an indexed Geom, so re-check the
@@ -267,10 +264,6 @@ int StandardMunger::
 compare_to_impl(const GeomMunger *other) const {
 compare_to_impl(const GeomMunger *other) const {
   const StandardMunger *om = (const StandardMunger *)other;
   const StandardMunger *om = (const StandardMunger *)other;
 
 
-  if (_render_mode != om->_render_mode) {
-    return _render_mode < om->_render_mode ? -1 : 1;
-  }
-
   if (_munge_color != om->_munge_color) {
   if (_munge_color != om->_munge_color) {
     return (int)_munge_color - (int)om->_munge_color;
     return (int)_munge_color - (int)om->_munge_color;
   }
   }

+ 0 - 3
panda/src/display/standardMunger.h

@@ -46,13 +46,10 @@ protected:
   virtual int geom_compare_to_impl(const GeomMunger *other) const;
   virtual int geom_compare_to_impl(const GeomMunger *other) const;
   virtual CPT(RenderState) munge_state_impl(const RenderState *state);
   virtual CPT(RenderState) munge_state_impl(const RenderState *state);
 
 
-  INLINE RenderModeAttrib::Mode get_render_mode() const;
-
 private:
 private:
   int _num_components;
   int _num_components;
   NumericType _numeric_type;
   NumericType _numeric_type;
   Contents _contents;
   Contents _contents;
-  CPT(RenderModeAttrib) _render_mode;
 
 
   bool _munge_color;
   bool _munge_color;
   bool _munge_color_scale;
   bool _munge_color_scale;

+ 0 - 4
panda/src/downloadertools/apply_patch.cxx

@@ -10,7 +10,6 @@
  */
  */
 
 
 #include "pandabase.h"
 #include "pandabase.h"
-#include "pystub.h"
 #include "panda_getopt.h"
 #include "panda_getopt.h"
 #include "preprocess_argv.h"
 #include "preprocess_argv.h"
 #include "patchfile.h"
 #include "patchfile.h"
@@ -18,9 +17,6 @@
 
 
 int
 int
 main(int argc, char **argv) {
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   preprocess_argv(argc, argv);
   preprocess_argv(argc, argv);
 
 
   if (argc < 3) {
   if (argc < 3) {

+ 0 - 4
panda/src/downloadertools/build_patch.cxx

@@ -10,7 +10,6 @@
  */
  */
 
 
 #include "pandabase.h"
 #include "pandabase.h"
-#include "pystub.h"
 #include "panda_getopt.h"
 #include "panda_getopt.h"
 #include "preprocess_argv.h"
 #include "preprocess_argv.h"
 #include "patchfile.h"
 #include "patchfile.h"
@@ -51,9 +50,6 @@ help() {
 
 
 int
 int
 main(int argc, char **argv) {
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   Filename patch_file;
   Filename patch_file;
   bool complete_file = false;
   bool complete_file = false;
   int footprint_length = 0;
   int footprint_length = 0;

+ 0 - 4
panda/src/downloadertools/check_adler.cxx

@@ -10,13 +10,9 @@
  */
  */
 
 
 #include "download_utils.h"
 #include "download_utils.h"
-#include "pystub.h"
 
 
 int
 int
 main(int argc, char *argv[]) {
 main(int argc, char *argv[]) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   if (argc < 2) {
   if (argc < 2) {
     cerr << "Usage: check_adler <file>" << endl;
     cerr << "Usage: check_adler <file>" << endl;
     return 1;
     return 1;

+ 0 - 4
panda/src/downloadertools/check_crc.cxx

@@ -10,13 +10,9 @@
  */
  */
 
 
 #include "download_utils.h"
 #include "download_utils.h"
-#include "pystub.h"
 
 
 int
 int
 main(int argc, char *argv[]) {
 main(int argc, char *argv[]) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   if (argc < 2) {
   if (argc < 2) {
     cerr << "Usage: check_crc <file>" << endl;
     cerr << "Usage: check_crc <file>" << endl;
     return 1;
     return 1;

+ 0 - 4
panda/src/downloadertools/check_md5.cxx

@@ -10,7 +10,6 @@
  */
  */
 
 
 #include "pandabase.h"
 #include "pandabase.h"
-#include "pystub.h"
 #include "hashVal.h"
 #include "hashVal.h"
 #include "filename.h"
 #include "filename.h"
 #include "panda_getopt.h"
 #include "panda_getopt.h"
@@ -65,9 +64,6 @@ output_hash(const string &filename, const HashVal &hash) {
 
 
 int
 int
 main(int argc, char **argv) {
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   extern char *optarg;
   extern char *optarg;
   extern int optind;
   extern int optind;
   const char *optstr = "i:db:qh";
   const char *optstr = "i:db:qh";

+ 0 - 4
panda/src/downloadertools/multify.cxx

@@ -10,7 +10,6 @@
  */
  */
 
 
 #include "pandabase.h"
 #include "pandabase.h"
-#include "pystub.h"
 #include "panda_getopt.h"
 #include "panda_getopt.h"
 #include "preprocess_argv.h"
 #include "preprocess_argv.h"
 #include "multifile.h"
 #include "multifile.h"
@@ -758,9 +757,6 @@ tokenize_extensions(const string &str, pset<string> &extensions) {
 
 
 int
 int
 main(int argc, char **argv) {
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   preprocess_argv(argc, argv);
   preprocess_argv(argc, argv);
   if (argc < 2) {
   if (argc < 2) {
     usage();
     usage();

+ 0 - 4
panda/src/downloadertools/pdecrypt.cxx

@@ -11,7 +11,6 @@
  * @date 2004-09-01
  * @date 2004-09-01
  */
  */
 
 
-#include "pystub.h"
 #include "filename.h"
 #include "filename.h"
 #include "encrypt_string.h"
 #include "encrypt_string.h"
 #include "pnotify.h"
 #include "pnotify.h"
@@ -46,9 +45,6 @@ usage() {
 
 
 int
 int
 main(int argc, char **argv) {
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   extern char *optarg;
   extern char *optarg;
   extern int optind;
   extern int optind;
   const char *optstr = "o:p:h";
   const char *optstr = "o:p:h";

+ 0 - 1
panda/src/downloadertools/pencrypt.cxx

@@ -11,7 +11,6 @@
  * @date 2004-09-01
  * @date 2004-09-01
  */
  */
 
 
-#include "pystub.h"
 #include "filename.h"
 #include "filename.h"
 #include "encrypt_string.h"
 #include "encrypt_string.h"
 #include "pnotify.h"
 #include "pnotify.h"

+ 0 - 4
panda/src/downloadertools/punzip.cxx

@@ -9,7 +9,6 @@
  * @file punzip.cxx
  * @file punzip.cxx
  */
  */
 
 
-#include "pystub.h"
 #include "filename.h"
 #include "filename.h"
 #include "compress_string.h"
 #include "compress_string.h"
 #include "pnotify.h"
 #include "pnotify.h"
@@ -31,9 +30,6 @@ usage() {
 
 
 int
 int
 main(int argc, char **argv) {
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   extern char *optarg;
   extern char *optarg;
   extern int optind;
   extern int optind;
   const char *optstr = "o:ch";
   const char *optstr = "o:ch";

+ 0 - 4
panda/src/downloadertools/pzip.cxx

@@ -9,7 +9,6 @@
  * @file pzip.cxx
  * @file pzip.cxx
  */
  */
 
 
-#include "pystub.h"
 #include "filename.h"
 #include "filename.h"
 #include "compress_string.h"
 #include "compress_string.h"
 #include "pnotify.h"
 #include "pnotify.h"
@@ -55,9 +54,6 @@ usage() {
 
 
 int
 int
 main(int argc, char **argv) {
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   extern char *optarg;
   extern char *optarg;
   extern int optind;
   extern int optind;
   const char *optstr = "o:c123456789h";
   const char *optstr = "o:c123456789h";

+ 0 - 4
panda/src/downloadertools/show_ddb.cxx

@@ -12,15 +12,11 @@
  */
  */
 
 
 #include "pandabase.h"
 #include "pandabase.h"
-#include "pystub.h"
 #include "downloadDb.h"
 #include "downloadDb.h"
 #include "filename.h"
 #include "filename.h"
 
 
 int
 int
 main(int argc, char *argv[]) {
 main(int argc, char *argv[]) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   if (argc != 3) {
   if (argc != 3) {
     cerr << "Usage: show_ddb server.ddb client.ddb\n";
     cerr << "Usage: show_ddb server.ddb client.ddb\n";
     return 1;
     return 1;

+ 59 - 30
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -403,10 +403,35 @@ extract_texture_data(Texture *tex) {
  */
  */
 ShaderContext *DXGraphicsStateGuardian9::
 ShaderContext *DXGraphicsStateGuardian9::
 prepare_shader(Shader *se) {
 prepare_shader(Shader *se) {
+  PStatTimer timer(_prepare_shader_pcollector);
+
+  switch (se->get_language()) {
+  case Shader::SL_GLSL:
+    dxgsg9_cat.error()
+      << "Tried to load GLSL shader, but GLSL shaders not supported by Direct3D 9.\n";
+    return NULL;
+
+  case Shader::SL_Cg:
 #ifdef HAVE_CG
 #ifdef HAVE_CG
-  CLP(ShaderContext) *result = new CLP(ShaderContext)(se, this);
-  return result;
+    if (_supports_basic_shaders) {
+      return new DXShaderContext9(se, this);
+    } else {
+      dxgsg9_cat.error()
+        << "Tried to load Cg shader, but basic shaders not supported.\n";
+      return NULL;
+    }
+#else
+    dxgsg9_cat.error()
+      << "Tried to load Cg shader, but Cg support not compiled in.\n";
+    return NULL;
 #endif
 #endif
+
+  default:
+    dxgsg9_cat.error()
+      << "Tried to load shader with unsupported shader language!\n";
+    return NULL;
+  }
+
   return NULL;
   return NULL;
 }
 }
 
 
@@ -415,7 +440,7 @@ prepare_shader(Shader *se) {
  */
  */
 void DXGraphicsStateGuardian9::
 void DXGraphicsStateGuardian9::
 release_shader(ShaderContext *sc) {
 release_shader(ShaderContext *sc) {
-  CLP(ShaderContext) *gsc = DCAST(CLP(ShaderContext), sc);
+  DXShaderContext9 *gsc = DCAST(DXShaderContext9, sc);
   delete gsc;
   delete gsc;
 }
 }
 
 
@@ -429,9 +454,9 @@ release_shader(ShaderContext *sc) {
  * This function should not be called directly to prepare a buffer.  Instead,
  * This function should not be called directly to prepare a buffer.  Instead,
  * call Geom::prepare().
  * call Geom::prepare().
  */
  */
-VertexBufferContext *CLP(GraphicsStateGuardian)::
+VertexBufferContext *DXGraphicsStateGuardian9::
 prepare_vertex_buffer(GeomVertexArrayData *data) {
 prepare_vertex_buffer(GeomVertexArrayData *data) {
-  CLP(VertexBufferContext) *dvbc = new CLP(VertexBufferContext)(this, _prepared_objects, data);
+  DXVertexBufferContext9 *dvbc = new DXVertexBufferContext9(this, _prepared_objects, data);
 
 
   DWORD usage;
   DWORD usage;
   D3DPOOL pool;
   D3DPOOL pool;
@@ -458,7 +483,7 @@ prepare_vertex_buffer(GeomVertexArrayData *data) {
 
 
   if (!FAILED(hr)) {
   if (!FAILED(hr)) {
     #if 0
     #if 0
-    if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
+    if (dxgsg9_cat.is_debug() && DXdebug_buffers9) {
       dxgsg9_cat.debug()
       dxgsg9_cat.debug()
         << "creating vertex buffer " << dvbc->_vbuffer << ": "
         << "creating vertex buffer " << dvbc->_vbuffer << ": "
         << data->get_num_rows() << " vertices "
         << data->get_num_rows() << " vertices "
@@ -481,16 +506,16 @@ prepare_vertex_buffer(GeomVertexArrayData *data) {
  * Updates the vertex buffer with the current data, and makes it the current
  * Updates the vertex buffer with the current data, and makes it the current
  * vertex buffer for rendering.
  * vertex buffer for rendering.
  */
  */
-bool CLP(GraphicsStateGuardian)::
+bool DXGraphicsStateGuardian9::
 apply_vertex_buffer(VertexBufferContext *vbc,
 apply_vertex_buffer(VertexBufferContext *vbc,
                     const GeomVertexArrayDataHandle *reader, bool force ) {
                     const GeomVertexArrayDataHandle *reader, bool force ) {
 
 
-  CLP(VertexBufferContext) *dvbc = DCAST(CLP(VertexBufferContext), vbc);
+  DXVertexBufferContext9 *dvbc = DCAST(DXVertexBufferContext9, vbc);
 
 
   if (dvbc->was_modified(reader)) {
   if (dvbc->was_modified(reader)) {
     int num_bytes = reader->get_data_size_bytes();
     int num_bytes = reader->get_data_size_bytes();
     #if 0
     #if 0
-    if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
+    if (dxgsg9_cat.is_debug() && DXdebug_buffers9) {
       dxgsg9_cat.debug()
       dxgsg9_cat.debug()
         << "copying " << num_bytes
         << "copying " << num_bytes
         << " bytes into vertex buffer " << dvbc->_vbuffer << "\n";
         << " bytes into vertex buffer " << dvbc->_vbuffer << "\n";
@@ -544,13 +569,13 @@ apply_vertex_buffer(VertexBufferContext *vbc,
  * should never be called directly; instead, call Data::release() (or simply
  * should never be called directly; instead, call Data::release() (or simply
  * let the Data destruct).
  * let the Data destruct).
  */
  */
-void CLP(GraphicsStateGuardian)::
+void DXGraphicsStateGuardian9::
 release_vertex_buffer(VertexBufferContext *vbc) {
 release_vertex_buffer(VertexBufferContext *vbc) {
 
 
-  CLP(VertexBufferContext) *dvbc = DCAST(CLP(VertexBufferContext), vbc);
+  DXVertexBufferContext9 *dvbc = DCAST(DXVertexBufferContext9, vbc);
 
 
   #if 0
   #if 0
-  if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
+  if (dxgsg9_cat.is_debug() && DXdebug_buffers9) {
     dxgsg9_cat.debug()
     dxgsg9_cat.debug()
       << "deleting vertex buffer " << dvbc->_vbuffer << "\n";
       << "deleting vertex buffer " << dvbc->_vbuffer << "\n";
   }
   }
@@ -575,8 +600,8 @@ release_vertex_buffer(VertexBufferContext *vbc) {
  * If force is not true, the function may return false indicating the data is
  * If force is not true, the function may return false indicating the data is
  * not currently available.
  * not currently available.
  */
  */
-bool CLP(GraphicsStateGuardian)::
-setup_array_data(CLP(VertexBufferContext)*& dvbc,
+bool DXGraphicsStateGuardian9::
+setup_array_data(DXVertexBufferContext9*& dvbc,
                  const GeomVertexArrayDataHandle* array_reader,
                  const GeomVertexArrayDataHandle* array_reader,
                  bool force) {
                  bool force) {
 
 
@@ -587,7 +612,7 @@ setup_array_data(CLP(VertexBufferContext)*& dvbc,
     return false;
     return false;
   }
   }
 
 
-  dvbc = (CLP(VertexBufferContext)*)vbc;
+  dvbc = (DXVertexBufferContext9*)vbc;
   return true;
   return true;
 }
 }
 
 
@@ -1028,17 +1053,17 @@ end_scene() {
   if (_vertex_array_shader_context != 0) {
   if (_vertex_array_shader_context != 0) {
     _vertex_array_shader_context->disable_shader_vertex_arrays(this);
     _vertex_array_shader_context->disable_shader_vertex_arrays(this);
     _vertex_array_shader = (Shader *)NULL;
     _vertex_array_shader = (Shader *)NULL;
-    _vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
+    _vertex_array_shader_context = (DXShaderContext9 *)NULL;
   }
   }
   if (_texture_binding_shader_context != 0) {
   if (_texture_binding_shader_context != 0) {
     _texture_binding_shader_context->disable_shader_texture_bindings(this);
     _texture_binding_shader_context->disable_shader_texture_bindings(this);
     _texture_binding_shader = (Shader *)NULL;
     _texture_binding_shader = (Shader *)NULL;
-    _texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
+    _texture_binding_shader_context = (DXShaderContext9 *)NULL;
   }
   }
   if (_current_shader_context != 0) {
   if (_current_shader_context != 0) {
     _current_shader_context->unbind(this);
     _current_shader_context->unbind(this);
     _current_shader = (Shader *)NULL;
     _current_shader = (Shader *)NULL;
-    _current_shader_context = (CLP(ShaderContext) *)NULL;
+    _current_shader_context = (DXShaderContext9 *)NULL;
   }
   }
 
 
   _dlights.clear();
   _dlights.clear();
@@ -1242,7 +1267,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
  * pipeline is about to be used - dxShaderContexts are responsible for setting
  * pipeline is about to be used - dxShaderContexts are responsible for setting
  * up their own vertex arrays.
  * up their own vertex arrays.
  */
  */
-bool CLP(GraphicsStateGuardian)::
+bool DXGraphicsStateGuardian9::
 update_standard_vertex_arrays(bool force) {
 update_standard_vertex_arrays(bool force) {
 
 
   int fvf = 0;
   int fvf = 0;
@@ -1257,7 +1282,7 @@ update_standard_vertex_arrays(bool force) {
     }
     }
 
 
     // Get the vertex buffer for this array.
     // Get the vertex buffer for this array.
-    CLP(VertexBufferContext)* dvbc;
+    DXVertexBufferContext9* dvbc;
     if (!setup_array_data(dvbc, array_reader, force)) {
     if (!setup_array_data(dvbc, array_reader, force)) {
       dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
       dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
       return false;
       return false;
@@ -1290,7 +1315,7 @@ update_standard_vertex_arrays(bool force) {
  * so, the standard streams need to be disabled to get them "out of the way."
  * so, the standard streams need to be disabled to get them "out of the way."
  * Called only from begin_draw_primitives.
  * Called only from begin_draw_primitives.
  */
  */
-void CLP(GraphicsStateGuardian)::
+void DXGraphicsStateGuardian9::
 disable_standard_vertex_arrays() {
 disable_standard_vertex_arrays() {
   for ( int array_index = 0; array_index < _num_bound_streams; ++array_index )
   for ( int array_index = 0; array_index < _num_bound_streams; ++array_index )
   {
   {
@@ -2184,7 +2209,8 @@ reset() {
     Geom::GR_point_perspective | Geom::GR_point_sprite |
     Geom::GR_point_perspective | Geom::GR_point_sprite |
     Geom::GR_indexed_other |
     Geom::GR_indexed_other |
     Geom::GR_triangle_strip | Geom::GR_triangle_fan |
     Geom::GR_triangle_strip | Geom::GR_triangle_fan |
-    Geom::GR_flat_first_vertex;
+    Geom::GR_flat_first_vertex |
+    Geom::GR_render_mode_wireframe | Geom::GR_render_mode_point;
 
 
   // overwrite gsg defaults with these values
   // overwrite gsg defaults with these values
 
 
@@ -2383,7 +2409,7 @@ reset() {
   // OVERRIDE SUPPORT SINCE IT DOES NOT WORK WELL
   // OVERRIDE SUPPORT SINCE IT DOES NOT WORK WELL
   _screen->_supports_automatic_mipmap_generation = false;
   _screen->_supports_automatic_mipmap_generation = false;
 
 
-  this -> reset_render_states ( );
+  reset_render_states();
 
 
   _max_vertices_per_array = d3d_caps.MaxVertexIndex;
   _max_vertices_per_array = d3d_caps.MaxVertexIndex;
   _max_vertices_per_primitive = d3d_caps.MaxPrimitiveCount;
   _max_vertices_per_primitive = d3d_caps.MaxPrimitiveCount;
@@ -2646,11 +2672,11 @@ reset() {
   set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD);
   set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD);
 
 
   _current_shader = (Shader *)NULL;
   _current_shader = (Shader *)NULL;
-  _current_shader_context = (CLP(ShaderContext) *)NULL;
+  _current_shader_context = (DXShaderContext9 *)NULL;
   _vertex_array_shader = (Shader *)NULL;
   _vertex_array_shader = (Shader *)NULL;
-  _vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
+  _vertex_array_shader_context = (DXShaderContext9 *)NULL;
   _texture_binding_shader = (Shader *)NULL;
   _texture_binding_shader = (Shader *)NULL;
-  _texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
+  _texture_binding_shader_context = (DXShaderContext9 *)NULL;
 
 
   PRINT_REFCNT(dxgsg9, _d3d_device);
   PRINT_REFCNT(dxgsg9, _d3d_device);
 
 
@@ -2775,13 +2801,13 @@ do_issue_alpha_test() {
 void DXGraphicsStateGuardian9::
 void DXGraphicsStateGuardian9::
 do_issue_shader() {
 do_issue_shader() {
 
 
-  CLP(ShaderContext) *context = 0;
+  DXShaderContext9 *context = 0;
   Shader *shader = 0;
   Shader *shader = 0;
   if (_target_shader) {
   if (_target_shader) {
     shader = (Shader *)(_target_shader->get_shader());
     shader = (Shader *)(_target_shader->get_shader());
   }
   }
   if (shader) {
   if (shader) {
-    context = (CLP(ShaderContext) *)(shader->prepare_now(get_prepared_objects(), this));
+    context = (DXShaderContext9 *)(shader->prepare_now(get_prepared_objects(), this));
   }
   }
 
 
   if (context == 0 || (context && context -> valid (this) == false)) {
   if (context == 0 || (context && context -> valid (this) == false)) {
@@ -2819,7 +2845,8 @@ do_issue_shader() {
  */
  */
 void DXGraphicsStateGuardian9::
 void DXGraphicsStateGuardian9::
 do_issue_render_mode() {
 do_issue_render_mode() {
-  const RenderModeAttrib *target_render_mode = DCAST(RenderModeAttrib, _target_rs->get_attrib_def(RenderModeAttrib::get_class_slot()));
+  const RenderModeAttrib *target_render_mode;
+  _target_rs->get_attrib_def(target_render_mode);
   RenderModeAttrib::Mode mode = target_render_mode->get_mode();
   RenderModeAttrib::Mode mode = target_render_mode->get_mode();
 
 
   switch (mode) {
   switch (mode) {
@@ -3395,6 +3422,8 @@ bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
 D3DFORMAT DXGraphicsStateGuardian9::
 D3DFORMAT DXGraphicsStateGuardian9::
 get_index_type(Geom::NumericType numeric_type) {
 get_index_type(Geom::NumericType numeric_type) {
   switch (numeric_type) {
   switch (numeric_type) {
+  // NT_uint8 is automatically promoted to uint16.
+  case Geom::NT_uint8:
   case Geom::NT_uint16:
   case Geom::NT_uint16:
     return D3DFMT_INDEX16;
     return D3DFMT_INDEX16;
 
 
@@ -4539,7 +4568,7 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
       }
       }
     }
     }
 
 
-    this -> mark_new();
+    mark_new();
     hr = _d3d_device->Reset(&_presentation_reset);
     hr = _d3d_device->Reset(&_presentation_reset);
     if (FAILED(hr) && hr != D3DERR_DEVICELOST) {
     if (FAILED(hr) && hr != D3DERR_DEVICELOST) {
       return hr;
       return hr;

+ 7 - 7
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -79,7 +79,7 @@ public:
                            bool force);
                            bool force);
   virtual void release_vertex_buffer(VertexBufferContext *vbc);
   virtual void release_vertex_buffer(VertexBufferContext *vbc);
 
 
-  bool setup_array_data(CLP(VertexBufferContext)*& vbc,
+  bool setup_array_data(DXVertexBufferContext9 *&vbc,
                         const GeomVertexArrayDataHandle* data,
                         const GeomVertexArrayDataHandle* data,
                         bool force);
                         bool force);
 
 
@@ -295,12 +295,12 @@ protected:
   CullFaceAttrib::Mode _cull_face_mode;
   CullFaceAttrib::Mode _cull_face_mode;
   RenderModeAttrib::Mode _current_fill_mode;  //point/wireframe/solid
   RenderModeAttrib::Mode _current_fill_mode;  //point/wireframe/solid
 
 
-  PT(Shader)  _current_shader;
-  CLP(ShaderContext)  *_current_shader_context;
-  PT(Shader)  _vertex_array_shader;
-  CLP(ShaderContext)  *_vertex_array_shader_context;
-  PT(Shader)  _texture_binding_shader;
-  CLP(ShaderContext)  *_texture_binding_shader_context;
+  PT(Shader) _current_shader;
+  DXShaderContext9 *_current_shader_context;
+  PT(Shader) _vertex_array_shader;
+  DXShaderContext9 *_vertex_array_shader_context;
+  PT(Shader) _texture_binding_shader;
+  DXShaderContext9 *_texture_binding_shader_context;
 
 
   const DXIndexBufferContext9 *_active_ibuffer;
   const DXIndexBufferContext9 *_active_ibuffer;
 
 

+ 30 - 23
panda/src/dxgsg9/dxIndexBufferContext9.cxx

@@ -27,9 +27,8 @@ TypeHandle DXIndexBufferContext9::_type_handle;
 DXIndexBufferContext9::
 DXIndexBufferContext9::
 DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
 DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
   IndexBufferContext(pgo, data),
   IndexBufferContext(pgo, data),
-  _ibuffer(NULL)
-{
-  _managed = -1;
+  _ibuffer(NULL),
+  _managed(-1) {
 }
 }
 
 
 /**
 /**
@@ -37,8 +36,7 @@ DXIndexBufferContext9(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
  */
  */
 DXIndexBufferContext9::
 DXIndexBufferContext9::
 ~DXIndexBufferContext9() {
 ~DXIndexBufferContext9() {
-
-  this -> free_ibuffer ( );
+  free_ibuffer();
 }
 }
 
 
 /**
 /**
@@ -70,13 +68,10 @@ free_ibuffer(void) {
         << "deleting index buffer " << _ibuffer << "\n";
         << "deleting index buffer " << _ibuffer << "\n";
     }
     }
 
 
-    if (DEBUG_INDEX_BUFFER)
-    {
+    if (DEBUG_INDEX_BUFFER) {
       RELEASE(_ibuffer, dxgsg9, "index buffer", RELEASE_ONCE);
       RELEASE(_ibuffer, dxgsg9, "index buffer", RELEASE_ONCE);
-    }
-    else
-    {
-      _ibuffer -> Release ( );
+    } else {
+      _ibuffer->Release();
     }
     }
 
 
     _ibuffer = NULL;
     _ibuffer = NULL;
@@ -99,6 +94,11 @@ allocate_ibuffer(DXScreenData &scrn,
 
 
   data_size = reader->get_data_size_bytes();
   data_size = reader->get_data_size_bytes();
 
 
+  if (reader->get_index_type() == GeomEnums::NT_uint8) {
+    // We widen 8-bits indices to 16-bits.
+    data_size *= 2;
+  }
+
   _managed = scrn._managed_index_buffers;
   _managed = scrn._managed_index_buffers;
   if (_managed)
   if (_managed)
   {
   {
@@ -147,16 +147,12 @@ create_ibuffer(DXScreenData &scrn,
   nassertv(reader->get_object() == get_data());
   nassertv(reader->get_object() == get_data());
   Thread *current_thread = reader->get_current_thread();
   Thread *current_thread = reader->get_current_thread();
 
 
-  this -> free_ibuffer ( );
+  free_ibuffer();
 
 
   PStatTimer timer(GraphicsStateGuardian::_create_index_buffer_pcollector,
   PStatTimer timer(GraphicsStateGuardian::_create_index_buffer_pcollector,
                    current_thread);
                    current_thread);
 
 
-  int data_size;
-
-  data_size = reader->get_data_size_bytes();
-
-  this -> allocate_ibuffer(scrn, reader);
+  allocate_ibuffer(scrn, reader);
 }
 }
 
 
 /**
 /**
@@ -175,6 +171,11 @@ upload_data(const GeomPrimitivePipelineReader *reader, bool force) {
   }
   }
   int data_size = reader->get_data_size_bytes();
   int data_size = reader->get_data_size_bytes();
 
 
+  if (reader->get_index_type() == GeomEnums::NT_uint8) {
+    // We widen 8-bits indices to 16-bits.
+    data_size *= 2;
+  }
+
   if (dxgsg9_cat.is_spam()) {
   if (dxgsg9_cat.is_spam()) {
     dxgsg9_cat.spam()
     dxgsg9_cat.spam()
       << "copying " << data_size
       << "copying " << data_size
@@ -186,12 +187,9 @@ upload_data(const GeomPrimitivePipelineReader *reader, bool force) {
   HRESULT hr;
   HRESULT hr;
   BYTE *local_pointer;
   BYTE *local_pointer;
 
 
-  if (_managed)
-  {
+  if (_managed) {
     hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, 0);
     hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, 0);
-  }
-  else
-  {
+  } else {
     hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, D3DLOCK_DISCARD);
     hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, D3DLOCK_DISCARD);
   }
   }
   if (FAILED(hr)) {
   if (FAILED(hr)) {
@@ -201,7 +199,16 @@ upload_data(const GeomPrimitivePipelineReader *reader, bool force) {
   }
   }
 
 
   GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
   GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
-  memcpy(local_pointer, data_pointer, data_size);
+
+  if (reader->get_index_type() == GeomEnums::NT_uint8) {
+    // Widen to 16-bits, as DirectX doesn't support 8-bits indices.
+    uint16_t *ptr = (uint16_t *)local_pointer;
+    for (size_t i = 0; i < data_size; i += 2) {
+      *ptr++ = (uint16_t)*data_pointer++;
+    }
+  } else {
+    memcpy(local_pointer, data_pointer, data_size);
+  }
 
 
   _ibuffer->Unlock();
   _ibuffer->Unlock();
   return true;
   return true;

+ 1 - 1
panda/src/dxgsg9/dxOcclusionQueryContext9.h

@@ -41,7 +41,7 @@ public:
   }
   }
   static void init_type() {
   static void init_type() {
     OcclusionQueryContext::init_type();
     OcclusionQueryContext::init_type();
-    register_type(_type_handle, CLASSPREFIX_QUOTED "OcclusionQueryContext",
+    register_type(_type_handle, "DXOcclusionQueryContext9",
                   OcclusionQueryContext::get_class_type());
                   OcclusionQueryContext::get_class_type());
   }
   }
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {

+ 1 - 1
panda/src/dxgsg9/dxShaderContext9.I

@@ -17,7 +17,7 @@
  * shader, or if the current video card isn't shader-capable, or if no shader
  * shader, or if the current video card isn't shader-capable, or if no shader
  * languages are compiled into panda.
  * languages are compiled into panda.
  */
  */
-INLINE bool CLP(ShaderContext)::
+INLINE bool DXShaderContext9::
 valid(GSG *gsg) {
 valid(GSG *gsg) {
 #ifdef HAVE_CG
 #ifdef HAVE_CG
   return (_cg_program != 0);
   return (_cg_program != 0);

+ 180 - 221
panda/src/dxgsg9/dxShaderContext9.cxx

@@ -28,13 +28,13 @@
 
 
 #define DEBUG_SHADER 0
 #define DEBUG_SHADER 0
 
 
-TypeHandle CLP(ShaderContext)::_type_handle;
+TypeHandle DXShaderContext9::_type_handle;
 
 
 /**
 /**
  * xyz
  * xyz
  */
  */
-CLP(ShaderContext)::
-CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
+DXShaderContext9::
+DXShaderContext9(Shader *s, GSG *gsg) : ShaderContext(s) {
   _vertex_element_array = NULL;
   _vertex_element_array = NULL;
   _vertex_declaration = NULL;
   _vertex_declaration = NULL;
 
 
@@ -46,7 +46,6 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
   CGcontext context = DCAST(DXGraphicsStateGuardian9, gsg)->_cg_context;
   CGcontext context = DCAST(DXGraphicsStateGuardian9, gsg)->_cg_context;
 
 
   if (s->get_language() == Shader::SL_Cg) {
   if (s->get_language() == Shader::SL_Cg) {
-
     // Ask the shader to compile itself for us and to give us the resulting Cg
     // Ask the shader to compile itself for us and to give us the resulting Cg
     // program objects.
     // program objects.
     if (!s->cg_compile_for(gsg->_shader_caps, context,
     if (!s->cg_compile_for(gsg->_shader_caps, context,
@@ -63,7 +62,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
     HRESULT hr;
     HRESULT hr;
     bool success = true;
     bool success = true;
     hr = cgD3D9LoadProgram(_cg_program, FALSE, assembly_flags);
     hr = cgD3D9LoadProgram(_cg_program, FALSE, assembly_flags);
-    if (FAILED (hr)) {
+    if (FAILED(hr)) {
       dxgsg9_cat.error()
       dxgsg9_cat.error()
         << "cgD3D9LoadProgram failed " << D3DERRORSTRING(hr);
         << "cgD3D9LoadProgram failed " << D3DERRORSTRING(hr);
 
 
@@ -80,46 +79,26 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
 /**
 /**
  * xyz
  * xyz
  */
  */
-CLP(ShaderContext)::
-~CLP(ShaderContext)() {
+DXShaderContext9::
+~DXShaderContext9() {
   release_resources();
   release_resources();
 
 
-  if ( _vertex_declaration != NULL ) {
+  if (_vertex_declaration != NULL) {
     _vertex_declaration->Release();
     _vertex_declaration->Release();
     _vertex_declaration = NULL;
     _vertex_declaration = NULL;
   }
   }
 
 
-  if ( _vertex_element_array != NULL ) {
+  if (_vertex_element_array != NULL) {
     delete _vertex_element_array;
     delete _vertex_element_array;
     _vertex_element_array = NULL;
     _vertex_element_array = NULL;
   }
   }
 }
 }
 
 
-/*
- * int save_file (int size, void *data, char *file_path) { int state; int
- * file_handle; state = false; file_handle = _open (file_path, _O_CREAT |
- * _O_RDWR | _O_TRUNC, _S_IREAD | _S_IWRITE); if (file_handle != -1) { if
- * (_write (file_handle, data, size) == size) { state = true; } _close
- * (file_handle); } return state; } if (dxgsg9_cat.is_debug()) { DEBUG: output
- * the generated program const char *vertex_program; const char
- * *pixel_program; vertex_program = cgGetProgramString (_cg_program[0],
- * CG_COMPILED_PROGRAM); pixel_program = cgGetProgramString (_cg_program[1],
- * CG_COMPILED_PROGRAM); dxgsg9_cat.debug() << vertex_program << "\n";
- * dxgsg9_cat.debug() << pixel_program << "\n"; save the generated program to
- * a file int size; char file_path [512]; char drive[_MAX_DRIVE]; char
- * dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; _splitpath
- * (_name.c_str ( ), drive, dir, fname, ext); size = strlen (vertex_program);
- * sprintf (file_path, "%s.vasm", fname); save_file (size, (void *)
- * vertex_program, file_path); size = strlen (pixel_program); sprintf
- * (file_path, "%s.pasm", fname); save_file (size, (void *) pixel_program,
- * file_path); }
- */
-
 /**
 /**
  * Should deallocate all system resources (such as vertex program handles or
  * Should deallocate all system resources (such as vertex program handles or
  * Cg contexts).
  * Cg contexts).
  */
  */
-void CLP(ShaderContext)::
+void DXShaderContext9::
 release_resources() {
 release_resources() {
 #ifdef HAVE_CG
 #ifdef HAVE_CG
   if (_cg_program) {
   if (_cg_program) {
@@ -139,9 +118,8 @@ release_resources() {
  * This function is to be called to enable a new shader.  It also initializes
  * This function is to be called to enable a new shader.  It also initializes
  * all of the shader's input parameters.
  * all of the shader's input parameters.
  */
  */
-bool CLP(ShaderContext)::
+bool DXShaderContext9::
 bind(GSG *gsg) {
 bind(GSG *gsg) {
-
   bool bind_state = false;
   bool bind_state = false;
 
 
 #ifdef HAVE_CG
 #ifdef HAVE_CG
@@ -149,7 +127,7 @@ bind(GSG *gsg) {
     // clear the last cached FVF to make sure the next SetFVF call goes
     // clear the last cached FVF to make sure the next SetFVF call goes
     // through
     // through
 
 
-    gsg -> _last_fvf = 0;
+    gsg->_last_fvf = 0;
 
 
     // Pass in k-parameters and transform-parameters
     // Pass in k-parameters and transform-parameters
     issue_parameters(gsg, Shader::SSD_general);
     issue_parameters(gsg, Shader::SSD_general);
@@ -159,7 +137,7 @@ bind(GSG *gsg) {
     // Bind the shaders.
     // Bind the shaders.
     bind_state = true;
     bind_state = true;
     hr = cgD3D9BindProgram(_cg_program);
     hr = cgD3D9BindProgram(_cg_program);
-    if (FAILED (hr)) {
+    if (FAILED(hr)) {
       dxgsg9_cat.error() << "cgD3D9BindProgram failed " << D3DERRORSTRING(hr);
       dxgsg9_cat.error() << "cgD3D9BindProgram failed " << D3DERRORSTRING(hr);
 
 
       CGerror error = cgGetError();
       CGerror error = cgGetError();
@@ -178,9 +156,8 @@ bind(GSG *gsg) {
 /**
 /**
  * This function disables a currently-bound shader.
  * This function disables a currently-bound shader.
  */
  */
-void CLP(ShaderContext)::
+void DXShaderContext9::
 unbind(GSG *gsg) {
 unbind(GSG *gsg) {
-
 #ifdef HAVE_CG
 #ifdef HAVE_CG
   if (_cg_program) {
   if (_cg_program) {
     HRESULT hr;
     HRESULT hr;
@@ -211,48 +188,59 @@ InternalName *global_internal_name_0 = 0;
 InternalName *global_internal_name_1 = 0;
 InternalName *global_internal_name_1 = 0;
 #endif
 #endif
 
 
-void CLP(ShaderContext)::
+void DXShaderContext9::
 issue_parameters(GSG *gsg, int altered) {
 issue_parameters(GSG *gsg, int altered) {
 #ifdef HAVE_CG
 #ifdef HAVE_CG
   if (_cg_program) {
   if (_cg_program) {
 
 
-  // Iterate through _ptr parameters
-    for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
-      if(altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])){
-#ifdef HAVE_CG
-        const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
-        Shader::ShaderPtrData* _ptr_data =
-          const_cast< Shader::ShaderPtrData*>(gsg->fetch_ptr_parameter(_ptr));
+    // Iterate through _ptr parameters
+    for (size_t i = 0; i < _shader->_ptr_spec.size(); ++i) {
+      const Shader::ShaderPtrSpec &spec = _shader->_ptr_spec[i];
+
+      if (altered & (spec._dep[0] | spec._dep[1])) {
+        const Shader::ShaderPtrData *ptr_data = gsg->fetch_ptr_parameter(spec);
 
 
-        if (_ptr_data == NULL){ //the input is not contained in ShaderPtrData
+        if (ptr_data == NULL) { //the input is not contained in ShaderPtrData
           release_resources();
           release_resources();
           return;
           return;
         }
         }
 
 
-        CGparameter p = _cg_parameter_map[_ptr._id._seqno];
+        // Calculate how many elements to transfer; no more than it expects,
+        // but certainly no more than we have.
+        int input_size = min(abs(spec._dim[0] * spec._dim[1] * spec._dim[2]), ptr_data->_size);
+
+        CGparameter p = _cg_parameter_map[spec._id._seqno];
+        switch (ptr_data->_type) {
+        case Shader::SPT_int:
+          cgSetParameterValueic(p, input_size, (int *)ptr_data->_ptr);
+          break;
+
+        case Shader::SPT_double:
+          cgSetParameterValuedc(p, input_size, (double *)ptr_data->_ptr);
+          break;
 
 
-        switch(_ptr_data->_type) {
         case Shader::SPT_float:
         case Shader::SPT_float:
-          cgD3D9SetUniform(p, (PN_stdfloat*)_ptr_data->_ptr);
+          cgSetParameterValuefc(p, input_size, (float *)ptr_data->_ptr);
           break;
           break;
 
 
         default:
         default:
           dxgsg9_cat.error()
           dxgsg9_cat.error()
-            << _ptr._id._name << ":" << "unrecognized parameter type\n";
+            << spec._id._name << ": unrecognized parameter type\n";
           release_resources();
           release_resources();
           return;
           return;
         }
         }
       }
       }
-#endif
     }
     }
 
 
-    for (int i=0; i<(int)_shader->_mat_spec.size(); i++) {
-      if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
-        CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
+    for (size_t i = 0; i < _shader->_mat_spec.size(); ++i) {
+      Shader::ShaderMatSpec &spec = _shader->_mat_spec[i];
+
+      if (altered & (spec._dep[0] | spec._dep[1])) {
+        CGparameter p = _cg_parameter_map[spec._id._seqno];
         if (p == NULL) {
         if (p == NULL) {
           continue;
           continue;
         }
         }
-        const LMatrix4 *val = gsg->fetch_specified_value(_shader->_mat_spec[i], altered);
+        const LMatrix4 *val = gsg->fetch_specified_value(spec, altered);
         if (val) {
         if (val) {
           HRESULT hr;
           HRESULT hr;
           PN_stdfloat v [4];
           PN_stdfloat v [4];
@@ -263,83 +251,79 @@ issue_parameters(GSG *gsg, int altered) {
           const float *data;
           const float *data;
           data = temp_matrix.get_data();
           data = temp_matrix.get_data();
 
 
-          #if DEBUG_SHADER
+#if DEBUG_SHADER
           // DEBUG
           // DEBUG
-          global_data = (PN_stdfloat *) data;
-          global_shader_mat_spec = &_shader->_mat_spec[i];
-          global_internal_name_0 = global_shader_mat_spec -> _arg [0];
-          global_internal_name_1 = global_shader_mat_spec -> _arg [1];
-          #endif
+          global_data = (PN_stdfloat *)data;
+          global_shader_mat_spec = &spec;
+          global_internal_name_0 = global_shader_mat_spec->_arg[0];
+          global_internal_name_1 = global_shader_mat_spec->_arg[1];
+#endif
 
 
-          switch (_shader->_mat_spec[i]._piece) {
+          switch (spec._piece) {
           case Shader::SMP_whole:
           case Shader::SMP_whole:
             // TRANSPOSE REQUIRED
             // TRANSPOSE REQUIRED
             temp_matrix.transpose_in_place();
             temp_matrix.transpose_in_place();
             data = temp_matrix.get_data();
             data = temp_matrix.get_data();
 
 
-            hr = cgD3D9SetUniform (p, data);
+            hr = cgD3D9SetUniform(p, data);
             break;
             break;
 
 
           case Shader::SMP_transpose:
           case Shader::SMP_transpose:
             // NO TRANSPOSE REQUIRED
             // NO TRANSPOSE REQUIRED
-            hr = cgD3D9SetUniform (p, data);
+            hr = cgD3D9SetUniform(p, data);
             break;
             break;
 
 
           case Shader::SMP_row0:
           case Shader::SMP_row0:
-            hr = cgD3D9SetUniform (p, data + 0);
+            hr = cgD3D9SetUniform(p, data + 0);
             break;
             break;
           case Shader::SMP_row1:
           case Shader::SMP_row1:
-            hr = cgD3D9SetUniform (p, data + 4);
+            hr = cgD3D9SetUniform(p, data + 4);
             break;
             break;
           case Shader::SMP_row2:
           case Shader::SMP_row2:
-            hr = cgD3D9SetUniform (p, data + 8);
+            hr = cgD3D9SetUniform(p, data + 8);
             break;
             break;
           case Shader::SMP_row3x1:
           case Shader::SMP_row3x1:
           case Shader::SMP_row3x2:
           case Shader::SMP_row3x2:
           case Shader::SMP_row3x3:
           case Shader::SMP_row3x3:
           case Shader::SMP_row3:
           case Shader::SMP_row3:
-            hr = cgD3D9SetUniform (p, data + 12);
+            hr = cgD3D9SetUniform(p, data + 12);
             break;
             break;
 
 
           case Shader::SMP_col0:
           case Shader::SMP_col0:
             v[0] = data[0]; v[1] = data[4]; v[2] = data[8]; v[3] = data[12];
             v[0] = data[0]; v[1] = data[4]; v[2] = data[8]; v[3] = data[12];
-            hr = cgD3D9SetUniform (p, v);
+            hr = cgD3D9SetUniform(p, v);
             break;
             break;
           case Shader::SMP_col1:
           case Shader::SMP_col1:
             v[0] = data[1]; v[1] = data[5]; v[2] = data[9]; v[3] = data[13];
             v[0] = data[1]; v[1] = data[5]; v[2] = data[9]; v[3] = data[13];
-            hr = cgD3D9SetUniform (p, v);
+            hr = cgD3D9SetUniform(p, v);
             break;
             break;
           case Shader::SMP_col2:
           case Shader::SMP_col2:
             v[0] = data[2]; v[1] = data[6]; v[2] = data[10]; v[3] = data[14];
             v[0] = data[2]; v[1] = data[6]; v[2] = data[10]; v[3] = data[14];
-            hr = cgD3D9SetUniform (p, v);
+            hr = cgD3D9SetUniform(p, v);
             break;
             break;
           case Shader::SMP_col3:
           case Shader::SMP_col3:
             v[0] = data[3]; v[1] = data[7]; v[2] = data[11]; v[3] = data[15];
             v[0] = data[3]; v[1] = data[7]; v[2] = data[11]; v[3] = data[15];
-            hr = cgD3D9SetUniform (p, v);
+            hr = cgD3D9SetUniform(p, v);
             break;
             break;
 
 
           default:
           default:
             dxgsg9_cat.error()
             dxgsg9_cat.error()
-              << "issue_parameters ( ) SMP parameter type not implemented " << _shader->_mat_spec[i]._piece << "\n";
+              << "issue_parameters () SMP parameter type not implemented " << spec._piece << "\n";
             break;
             break;
           }
           }
 
 
-          if (FAILED (hr)) {
-
+          if (FAILED(hr)) {
             string name = "unnamed";
             string name = "unnamed";
 
 
-            if (_shader->_mat_spec[i]._arg [0]) {
-              name = _shader->_mat_spec[i]._arg [0] -> get_basename ( );
+            if (spec._arg[0]) {
+              name = spec._arg[0]->get_basename();
             }
             }
 
 
             dxgsg9_cat.error()
             dxgsg9_cat.error()
-              << "NAME  " << name << "\n"
-              << "MAT TYPE  "
-              << _shader->_mat_spec[i]._piece
-              << " cgD3D9SetUniform failed "
-              << D3DERRORSTRING(hr);
+              << "NAME  " << name << "\n" << "MAT TYPE  " << spec._piece
+              << " cgD3D9SetUniform failed " << D3DERRORSTRING(hr);
 
 
-            CGerror error = cgGetError ();
+            CGerror error = cgGetError();
             if (error != CG_NO_ERROR) {
             if (error != CG_NO_ERROR) {
               dxgsg9_cat.error() << "  CG ERROR: " << cgGetErrorString(error) << "\n";
               dxgsg9_cat.error() << "  CG ERROR: " << cgGetErrorString(error) << "\n";
             }
             }
@@ -354,13 +338,12 @@ issue_parameters(GSG *gsg, int altered) {
 /**
 /**
  * Disable all the vertex arrays used by this shader.
  * Disable all the vertex arrays used by this shader.
  */
  */
-void CLP(ShaderContext)::
+void DXShaderContext9::
 disable_shader_vertex_arrays(GSG *gsg) {
 disable_shader_vertex_arrays(GSG *gsg) {
   LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
   LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
 
 
-  for ( int array_index = 0; array_index < _num_bound_streams; ++array_index )
-  {
-    device->SetStreamSource( array_index, NULL, 0, 0 );
+  for (int array_index = 0; array_index < _num_bound_streams; ++array_index) {
+    device->SetStreamSource(array_index, NULL, 0, 0);
   }
   }
   _num_bound_streams = 0;
   _num_bound_streams = 0;
 }
 }
@@ -372,8 +355,8 @@ disable_shader_vertex_arrays(GSG *gsg) {
  * because it may unnecessarily disable arrays then immediately reenable them.
  * because it may unnecessarily disable arrays then immediately reenable them.
  * We may optimize this someday.
  * We may optimize this someday.
  */
  */
-bool CLP(ShaderContext)::
-update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
+bool DXShaderContext9::
+update_shader_vertex_arrays(DXShaderContext9 *prev, GSG *gsg, bool force) {
   if (prev) prev->disable_shader_vertex_arrays(gsg);
   if (prev) prev->disable_shader_vertex_arrays(gsg);
 #ifdef HAVE_CG
 #ifdef HAVE_CG
   if (!_cg_program) {
   if (!_cg_program) {
@@ -394,7 +377,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
 
 
     // Discard and recreate the VertexElementArray.  This thrashes pretty
     // Discard and recreate the VertexElementArray.  This thrashes pretty
     // bad....
     // bad....
-    if ( _vertex_element_array != NULL ) {
+    if (_vertex_element_array != NULL) {
       delete _vertex_element_array;
       delete _vertex_element_array;
     }
     }
     _vertex_element_array = new VertexElementArray(nvarying + 2);
     _vertex_element_array = new VertexElementArray(nvarying + 2);
@@ -408,17 +391,17 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
     // out only those for a single stream.
     // out only those for a single stream.
 
 
     int number_of_arrays = gsg->_data_reader->get_num_arrays();
     int number_of_arrays = gsg->_data_reader->get_num_arrays();
-    for ( int array_index = 0; array_index < number_of_arrays; ++array_index ) {
+    for (int array_index = 0; array_index < number_of_arrays; ++array_index) {
       const GeomVertexArrayDataHandle* array_reader =
       const GeomVertexArrayDataHandle* array_reader =
-        gsg->_data_reader->get_array_reader( array_index );
-      if ( array_reader == NULL ) {
+        gsg->_data_reader->get_array_reader(array_index);
+      if (array_reader == NULL) {
         dxgsg9_cat.error() << "Unable to get reader for array " << array_index << "\n";
         dxgsg9_cat.error() << "Unable to get reader for array " << array_index << "\n";
         continue;
         continue;
       }
       }
 
 
-      for ( int var_index = 0; var_index < nvarying; ++var_index ) {
+      for (int var_index = 0; var_index < nvarying; ++var_index) {
         CGparameter p = _cg_parameter_map[_shader->_var_spec[var_index]._id._seqno];
         CGparameter p = _cg_parameter_map[_shader->_var_spec[var_index]._id._seqno];
-        if ( p == NULL ) {
+        if (p == NULL) {
           dxgsg9_cat.info() <<
           dxgsg9_cat.info() <<
             "No parameter in map for parameter " << var_index <<
             "No parameter in map for parameter " << var_index <<
             " (probably optimized away)\n";
             " (probably optimized away)\n";
@@ -440,14 +423,12 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
           }
           }
         }
         }
 
 
-        const GeomVertexArrayDataHandle* param_array_reader;
+        const GeomVertexArrayDataHandle *param_array_reader;
         Geom::NumericType numeric_type;
         Geom::NumericType numeric_type;
-        int num_values;
-        int start;
-        int stride;
-        if ( gsg->_data_reader->get_array_info( name,
-                                                param_array_reader, num_values, numeric_type,
-                                                start, stride ) == false ) {
+        int num_values, start, stride;
+        if (!gsg->_data_reader->get_array_info(name, param_array_reader,
+                                               num_values, numeric_type,
+                                               start, stride)) {
           // This is apparently not an error (actually I think it is, just not
           // This is apparently not an error (actually I think it is, just not
           // a fatal one). The GL implementation fails silently in this case,
           // a fatal one). The GL implementation fails silently in this case,
           // but the net result is that we end up not supplying input for a
           // but the net result is that we end up not supplying input for a
@@ -458,105 +439,105 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
         }
         }
 
 
         // If not associated with the array we're working on, move on.
         // If not associated with the array we're working on, move on.
-        if ( param_array_reader != array_reader ) {
+        if (param_array_reader != array_reader) {
           continue;
           continue;
         }
         }
 
 
-        const char* semantic = cgGetParameterSemantic( p );
-        if ( semantic == NULL ) {
+        const char *semantic = cgGetParameterSemantic(p);
+        if (semantic == NULL) {
           dxgsg9_cat.error() << "Unable to retrieve semantic for parameter " << var_index << "\n";
           dxgsg9_cat.error() << "Unable to retrieve semantic for parameter " << var_index << "\n";
           continue;
           continue;
         }
         }
 
 
-        if ( strncmp( semantic, "POSITION", strlen( "POSITION" ) ) == 0 ) {
+        if (strncmp(semantic, "POSITION", strlen("POSITION")) == 0) {
           if (numeric_type == Geom::NT_float32) {
           if (numeric_type == Geom::NT_float32) {
             switch (num_values) {
             switch (num_values) {
-              case 3:
-                vertex_element_array->add_position_xyz_vertex_element(array_index, start);
-                break;
-              case 4:
-                vertex_element_array->add_position_xyzw_vertex_element(array_index, start);
-                break;
-              default:
-                dxgsg9_cat.error() << "VE ERROR: invalid number of vertex coordinate elements " << num_values << "\n";
-                break;
+            case 3:
+              vertex_element_array->add_position_xyz_vertex_element(array_index, start);
+              break;
+            case 4:
+              vertex_element_array->add_position_xyzw_vertex_element(array_index, start);
+              break;
+            default:
+              dxgsg9_cat.error() << "VE ERROR: invalid number of vertex coordinate elements " << num_values << "\n";
+              break;
             }
             }
           } else {
           } else {
             dxgsg9_cat.error() << "VE ERROR: invalid vertex type " << numeric_type << "\n";
             dxgsg9_cat.error() << "VE ERROR: invalid vertex type " << numeric_type << "\n";
           }
           }
-        } else if ( strncmp( semantic, "TEXCOORD", strlen( "TEXCOORD" ) ) == 0 ) {
-          int slot = atoi( semantic + strlen( "TEXCOORD" ) );
+        } else if (strncmp(semantic, "TEXCOORD", strlen("TEXCOORD")) == 0) {
+          int slot = atoi(semantic + strlen("TEXCOORD"));
           if (numeric_type == Geom::NT_float32) {
           if (numeric_type == Geom::NT_float32) {
             switch (num_values) {
             switch (num_values) {
-              case 1:
-                vertex_element_array->add_u_vertex_element(array_index, start, slot);
-                break;
-              case 2:
-                vertex_element_array->add_uv_vertex_element(array_index, start, slot);
-                break;
-              case 3:
-                vertex_element_array->add_uvw_vertex_element(array_index, start, slot);
-                break;
-              case 4:
-                vertex_element_array->add_xyzw_vertex_element(array_index, start, slot);
-                break;
-              default:
-                dxgsg9_cat.error() << "VE ERROR: invalid number of vertex texture coordinate elements " << num_values <<  "\n";
-                break;
+            case 1:
+              vertex_element_array->add_u_vertex_element(array_index, start, slot);
+              break;
+            case 2:
+              vertex_element_array->add_uv_vertex_element(array_index, start, slot);
+              break;
+            case 3:
+              vertex_element_array->add_uvw_vertex_element(array_index, start, slot);
+              break;
+            case 4:
+              vertex_element_array->add_xyzw_vertex_element(array_index, start, slot);
+              break;
+            default:
+              dxgsg9_cat.error() << "VE ERROR: invalid number of vertex texture coordinate elements " << num_values <<  "\n";
+              break;
             }
             }
           } else {
           } else {
             dxgsg9_cat.error() << "VE ERROR: invalid texture coordinate type " << numeric_type << "\n";
             dxgsg9_cat.error() << "VE ERROR: invalid texture coordinate type " << numeric_type << "\n";
           }
           }
-        } else if ( strncmp( semantic, "COLOR", strlen( "COLOR" ) ) == 0 ) {
+        } else if (strncmp(semantic, "COLOR", strlen("COLOR")) == 0) {
           if (numeric_type == Geom::NT_packed_dcba ||
           if (numeric_type == Geom::NT_packed_dcba ||
               numeric_type == Geom::NT_packed_dabc ||
               numeric_type == Geom::NT_packed_dabc ||
               numeric_type == Geom::NT_uint8) {
               numeric_type == Geom::NT_uint8) {
             switch (num_values) {
             switch (num_values) {
-              case 4:
-                vertex_element_array->add_diffuse_color_vertex_element(array_index, start);
-                break;
-              default:
-                dxgsg9_cat.error() << "VE ERROR: invalid color coordinates " << num_values << "\n";
-                break;
+            case 4:
+              vertex_element_array->add_diffuse_color_vertex_element(array_index, start);
+              break;
+            default:
+              dxgsg9_cat.error() << "VE ERROR: invalid color coordinates " << num_values << "\n";
+              break;
             }
             }
           } else {
           } else {
             dxgsg9_cat.error() << "VE ERROR: invalid color type " << numeric_type << "\n";
             dxgsg9_cat.error() << "VE ERROR: invalid color type " << numeric_type << "\n";
           }
           }
-        } else if ( strncmp( semantic, "NORMAL", strlen( "NORMAL" ) ) == 0 ) {
+        } else if (strncmp(semantic, "NORMAL", strlen("NORMAL")) == 0) {
           if (numeric_type == Geom::NT_float32) {
           if (numeric_type == Geom::NT_float32) {
             switch (num_values) {
             switch (num_values) {
-              case 3:
-                vertex_element_array->add_normal_vertex_element(array_index, start);
-                break;
-              default:
-                dxgsg9_cat.error() << "VE ERROR: invalid number of normal coordinate elements " << num_values << "\n";
-                break;
+            case 3:
+              vertex_element_array->add_normal_vertex_element(array_index, start);
+              break;
+            default:
+              dxgsg9_cat.error() << "VE ERROR: invalid number of normal coordinate elements " << num_values << "\n";
+              break;
             }
             }
           } else {
           } else {
             dxgsg9_cat.error() << "VE ERROR: invalid normal type " << numeric_type << "\n";
             dxgsg9_cat.error() << "VE ERROR: invalid normal type " << numeric_type << "\n";
           }
           }
-        } else if ( strncmp( semantic, "BINORMAL", strlen( "BINORMAL" ) ) == 0 ) {
+        } else if (strncmp(semantic, "BINORMAL", strlen("BINORMAL")) == 0) {
           if (numeric_type == Geom::NT_float32) {
           if (numeric_type == Geom::NT_float32) {
             switch (num_values) {
             switch (num_values) {
-              case 3:
-                vertex_element_array->add_binormal_vertex_element(array_index, start);
-                break;
-              default:
-                dxgsg9_cat.error() << "VE ERROR: invalid number of binormal coordinate elements " << num_values << "\n";
-                break;
+            case 3:
+              vertex_element_array->add_binormal_vertex_element(array_index, start);
+              break;
+            default:
+              dxgsg9_cat.error() << "VE ERROR: invalid number of binormal coordinate elements " << num_values << "\n";
+              break;
             }
             }
           } else {
           } else {
             dxgsg9_cat.error() << "VE ERROR: invalid binormal type " << numeric_type << "\n";
             dxgsg9_cat.error() << "VE ERROR: invalid binormal type " << numeric_type << "\n";
           }
           }
-        } else if ( strncmp( semantic, "TANGENT", strlen( "TANGENT" ) ) == 0 ) {
+        } else if (strncmp(semantic, "TANGENT", strlen("TANGENT")) == 0) {
           if (numeric_type == Geom::NT_float32) {
           if (numeric_type == Geom::NT_float32) {
             switch (num_values) {
             switch (num_values) {
-              case 3:
-                vertex_element_array->add_tangent_vertex_element(array_index, start);
-                break;
-              default:
-                dxgsg9_cat.error() << "VE ERROR: invalid number of tangent coordinate elements " << num_values << "\n";
-                break;
+            case 3:
+              vertex_element_array->add_tangent_vertex_element(array_index, start);
+              break;
+            default:
+              dxgsg9_cat.error() << "VE ERROR: invalid number of tangent coordinate elements " << num_values << "\n";
+              break;
             }
             }
           } else {
           } else {
             dxgsg9_cat.error() << "VE ERROR: invalid tangent type " << numeric_type << "\n";
             dxgsg9_cat.error() << "VE ERROR: invalid tangent type " << numeric_type << "\n";
@@ -567,15 +548,15 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
       }
       }
 
 
       // Get the vertex buffer for this array.
       // Get the vertex buffer for this array.
-      CLP(VertexBufferContext)* dvbc;
+      DXVertexBufferContext9 *dvbc;
       if (!gsg->setup_array_data(dvbc, array_reader, force)) {
       if (!gsg->setup_array_data(dvbc, array_reader, force)) {
         dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
         dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
         continue;
         continue;
       }
       }
 
 
       // Bind this array as the data source for the corresponding stream.
       // Bind this array as the data source for the corresponding stream.
-      const GeomVertexArrayFormat* array_format = array_reader->get_array_format();
-      hr = device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() );
+      const GeomVertexArrayFormat *array_format = array_reader->get_array_format();
+      hr = device->SetStreamSource(array_index, dvbc->_vbuffer, 0, array_format->get_stride());
       if (FAILED(hr)) {
       if (FAILED(hr)) {
         dxgsg9_cat.error() << "SetStreamSource failed" << D3DERRORSTRING(hr);
         dxgsg9_cat.error() << "SetStreamSource failed" << D3DERRORSTRING(hr);
       }
       }
@@ -583,8 +564,8 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
 
 
     _num_bound_streams = number_of_arrays;
     _num_bound_streams = number_of_arrays;
 
 
-    if (( _vertex_element_array != NULL ) &&
-        ( _vertex_element_array->add_end_vertex_element() != false )) {
+    if (_vertex_element_array != NULL &&
+        _vertex_element_array->add_end_vertex_element()) {
       if (dxgsg9_cat.is_debug()) {
       if (dxgsg9_cat.is_debug()) {
         // Note that the currently generated vertex declaration works but
         // Note that the currently generated vertex declaration works but
         // never validates.  My theory is that this is due to the shader
         // never validates.  My theory is that this is due to the shader
@@ -599,17 +580,17 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
       }
       }
 
 
       // Discard the old VertexDeclaration.  This thrashes pretty bad....
       // Discard the old VertexDeclaration.  This thrashes pretty bad....
-      if ( _vertex_declaration != NULL ) {
+      if (_vertex_declaration != NULL) {
         _vertex_declaration->Release();
         _vertex_declaration->Release();
         _vertex_declaration = NULL;
         _vertex_declaration = NULL;
       }
       }
 
 
-      hr = device->CreateVertexDeclaration( _vertex_element_array->_vertex_element_array,
-                                            &_vertex_declaration );
-      if (FAILED (hr)) {
+      hr = device->CreateVertexDeclaration(_vertex_element_array->_vertex_element_array,
+                                           &_vertex_declaration);
+      if (FAILED(hr)) {
         dxgsg9_cat.error() << "CreateVertexDeclaration failed" << D3DERRORSTRING(hr);
         dxgsg9_cat.error() << "CreateVertexDeclaration failed" << D3DERRORSTRING(hr);
       } else {
       } else {
-        hr = device->SetVertexDeclaration( _vertex_declaration );
+        hr = device->SetVertexDeclaration(_vertex_declaration);
         if (FAILED(hr)) {
         if (FAILED(hr)) {
           dxgsg9_cat.error() << "SetVertexDeclaration failed" << D3DERRORSTRING(hr);
           dxgsg9_cat.error() << "SetVertexDeclaration failed" << D3DERRORSTRING(hr);
         }
         }
@@ -626,12 +607,11 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
 /**
 /**
  * Disable all the texture bindings used by this shader.
  * Disable all the texture bindings used by this shader.
  */
  */
-void CLP(ShaderContext)::
-disable_shader_texture_bindings(GSG *gsg)
-{
+void DXShaderContext9::
+disable_shader_texture_bindings(GSG *gsg) {
 #ifdef HAVE_CG
 #ifdef HAVE_CG
   if (_cg_program) {
   if (_cg_program) {
-    for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
+    for (size_t i = 0; i < _shader->_tex_spec.size(); ++i) {
       CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
       CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
       if (p == NULL) {
       if (p == NULL) {
         continue;
         continue;
@@ -640,12 +620,10 @@ disable_shader_texture_bindings(GSG *gsg)
 
 
       HRESULT hr;
       HRESULT hr;
 
 
-      hr = gsg -> _d3d_device -> SetTexture (texunit, NULL);
-      if (FAILED (hr)) {
+      hr = gsg->_d3d_device->SetTexture(texunit, NULL);
+      if (FAILED(hr)) {
         dxgsg9_cat.error()
         dxgsg9_cat.error()
-          << "SetTexture ("
-          << texunit
-          << ", NULL) failed "
+          << "SetTexture(" << texunit << ", NULL) failed "
           << D3DERRORSTRING(hr);
           << D3DERRORSTRING(hr);
       }
       }
     }
     }
@@ -660,60 +638,44 @@ disable_shader_texture_bindings(GSG *gsg)
  * because it may unnecessarily disable textures then immediately reenable
  * because it may unnecessarily disable textures then immediately reenable
  * them.  We may optimize this someday.
  * them.  We may optimize this someday.
  */
  */
-void CLP(ShaderContext)::
-update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
-{
-  if (prev) prev->disable_shader_texture_bindings(gsg);
+void DXShaderContext9::
+update_shader_texture_bindings(DXShaderContext9 *prev, GSG *gsg) {
+  if (prev) {
+    prev->disable_shader_texture_bindings(gsg);
+  }
 
 
 #ifdef HAVE_CG
 #ifdef HAVE_CG
   if (_cg_program) {
   if (_cg_program) {
-
-    for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
-      CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
+    for (size_t i = 0; i < _shader->_tex_spec.size(); ++i) {
+      Shader::ShaderTexSpec &spec = _shader->_tex_spec[i];
+      CGparameter p = _cg_parameter_map[spec._id._seqno];
       if (p == NULL) {
       if (p == NULL) {
         continue;
         continue;
       }
       }
-      Texture *tex = NULL;
+
       int view = gsg->get_current_tex_view_offset();
       int view = gsg->get_current_tex_view_offset();
-      InternalName *id = _shader->_tex_spec[i]._name;
       SamplerState sampler;
       SamplerState sampler;
 
 
-      if (id != NULL) {
-        const ShaderInput *input = gsg->_target_shader->get_shader_input(id);
-        tex = input->get_texture();
-        sampler = input->get_sampler();
-
-      } else {
-        // We get the TextureAttrib directly from the _target_rs, not the
-        // filtered TextureAttrib in _target_texture.
-        const TextureAttrib *texattrib = DCAST(TextureAttrib, gsg->_target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
-        nassertv(texattrib != (TextureAttrib *)NULL);
-
-        if (_shader->_tex_spec[i]._stage >= texattrib->get_num_on_stages()) {
-          continue;
-        }
-        TextureStage *stage = texattrib->get_on_stage(_shader->_tex_spec[i]._stage);
-        tex = texattrib->get_on_texture(stage);
-        sampler = texattrib->get_on_sampler(stage);
-        view += stage->get_tex_view_offset();
+      PT(Texture) tex = gsg->fetch_specified_texture(spec, sampler, view);
+      if (tex.is_null()) {
+        continue;
       }
       }
-      if (_shader->_tex_spec[i]._suffix != 0) {
+
+      if (spec._suffix != 0) {
         // The suffix feature is inefficient.  It is a temporary hack.
         // The suffix feature is inefficient.  It is a temporary hack.
-        if (tex == 0) {
-          continue;
-        }
-        tex = tex->load_related(_shader->_tex_spec[i]._suffix);
+        tex = tex->load_related(spec._suffix);
       }
       }
-      if ((tex == 0) || (tex->get_texture_type() != _shader->_tex_spec[i]._desired_type)) {
+
+      if (tex->get_texture_type() != spec._desired_type) {
         continue;
         continue;
       }
       }
+
       TextureContext *tc = tex->prepare_now(view, gsg->_prepared_objects, gsg);
       TextureContext *tc = tex->prepare_now(view, gsg->_prepared_objects, gsg);
       if (tc == (TextureContext*)NULL) {
       if (tc == (TextureContext*)NULL) {
         continue;
         continue;
       }
       }
 
 
       int texunit = cgGetParameterResourceIndex(p);
       int texunit = cgGetParameterResourceIndex(p);
-
       gsg->apply_texture(texunit, tc, sampler);
       gsg->apply_texture(texunit, tc, sampler);
     }
     }
   }
   }
@@ -721,8 +683,7 @@ update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
 }
 }
 
 
 // DEBUG CODE TO TEST ASM CODE GENERATED BY Cg
 // DEBUG CODE TO TEST ASM CODE GENERATED BY Cg
-void assemble_shader_test(char *file_path)
-{
+void assemble_shader_test(char *file_path) {
   int flags;
   int flags;
   D3DXMACRO *defines;
   D3DXMACRO *defines;
   LPD3DXINCLUDE include;
   LPD3DXINCLUDE include;
@@ -735,17 +696,15 @@ void assemble_shader_test(char *file_path)
   shader = 0;
   shader = 0;
   error_messages = 0;
   error_messages = 0;
 
 
-  D3DXAssembleShaderFromFile (file_path, defines, include, flags, &shader, &error_messages);
-  if (error_messages)
-  {
+  D3DXAssembleShaderFromFile(file_path, defines, include, flags, &shader, &error_messages);
+  if (error_messages) {
     char *error_message;
     char *error_message;
 
 
-    error_message = (char *) (error_messages -> GetBufferPointer ( ));
-    if (error_message)
-    {
+    error_message = (char *)error_messages->GetBufferPointer();
+    if (error_message) {
       dxgsg9_cat.error() << error_message;
       dxgsg9_cat.error() << error_message;
     }
     }
 
 
-    error_messages -> Release ( );
+    error_messages->Release();
   }
   }
 }
 }

+ 36 - 23
panda/src/dxgsg9/dxShaderContext9.h

@@ -21,33 +21,46 @@
 #include "shader.h"
 #include "shader.h"
 #include "shaderContext.h"
 #include "shaderContext.h"
 
 
-#define CLP(name) DX##name##9
-#define CLASSPREFIX_QUOTED "DX"
-
 class VertexElementArray;
 class VertexElementArray;
-class CLP(GraphicsStateGuardian);
-
-/*
- * Caution: adding HLSL support is going to be tricky, as the parsing needs to
- * be done in the cull thread, which cannot use the DX API.  - Josh typedef
- * struct { int vertex_shader; int total_constant_descriptions;
- * D3DXCONSTANT_DESC *constant_description_array; } DX_PARAMETER; typedef
- * struct { int state; union { DIRECT_3D_VERTEX_SHADER
- * direct_3d_vertex_shader; DIRECT_3D_PIXEL_SHADER direct_3d_pixel_shader; };
- * LPD3DXCONSTANTTABLE constant_table; D3DXCONSTANTTABLE_DESC
- * constant_table_description; int total_semantics; D3DXSEMANTIC
- * *semantic_array; } DIRECT_3D_SHADER;
- */
+class DXGraphicsStateGuardian9;
+
+// Caution: adding HLSL support is going to be tricky, as the parsing needs to
+// be done in the cull thread, which cannot use the DX API.  - Josh
+//
+//
+// typedef struct
+// {
+//   int vertex_shader;
+//   int total_constant_descriptions;
+//   D3DXCONSTANT_DESC *constant_description_array;
+// }
+// DX_PARAMETER;
+//
+// typedef struct
+// {
+//   int state;
+//   union
+//   {
+//     DIRECT_3D_VERTEX_SHADER direct_3d_vertex_shader;
+//     DIRECT_3D_PIXEL_SHADER direct_3d_pixel_shader;
+//   };
+//   LPD3DXCONSTANTTABLE constant_table;
+//   D3DXCONSTANTTABLE_DESC constant_table_description;
+//
+//   int total_semantics;
+//   D3DXSEMANTIC *semantic_array;
+// }
+// DIRECT_3D_SHADER;
 
 
 /**
 /**
  * xyz
  * xyz
  */
  */
-class EXPCL_PANDADX CLP(ShaderContext) : public ShaderContext {
+class EXPCL_PANDADX DXShaderContext9 : public ShaderContext {
 public:
 public:
-  typedef CLP(GraphicsStateGuardian) GSG;
+  typedef DXGraphicsStateGuardian9 GSG;
 
 
-  CLP(ShaderContext)(Shader *s, GSG *gsg);
-  ~CLP(ShaderContext)();
+  DXShaderContext9(Shader *s, GSG *gsg);
+  ~DXShaderContext9();
 
 
   INLINE bool valid(GSG *gsg);
   INLINE bool valid(GSG *gsg);
   bool bind(GSG *gsg);
   bool bind(GSG *gsg);
@@ -55,10 +68,10 @@ public:
   void issue_parameters(GSG *gsg, int altered);
   void issue_parameters(GSG *gsg, int altered);
   void issue_transform(GSG *gsg);
   void issue_transform(GSG *gsg);
   void disable_shader_vertex_arrays(GSG *gsg);
   void disable_shader_vertex_arrays(GSG *gsg);
-  bool update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg,
+  bool update_shader_vertex_arrays(DXShaderContext9 *prev, GSG *gsg,
                                    bool force);
                                    bool force);
   void disable_shader_texture_bindings(GSG *gsg);
   void disable_shader_texture_bindings(GSG *gsg);
-  void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg);
+  void update_shader_texture_bindings(DXShaderContext9 *prev, GSG *gsg);
 
 
   class VertexElementArray* _vertex_element_array;
   class VertexElementArray* _vertex_element_array;
   LPDIRECT3DVERTEXDECLARATION9 _vertex_declaration;
   LPDIRECT3DVERTEXDECLARATION9 _vertex_declaration;
@@ -83,7 +96,7 @@ public:
   }
   }
   static void init_type() {
   static void init_type() {
     TypedObject::init_type();
     TypedObject::init_type();
-    register_type(_type_handle, CLASSPREFIX_QUOTED "ShaderContext",
+    register_type(_type_handle, "DXShaderContext9",
                   TypedObject::get_class_type());
                   TypedObject::get_class_type());
   }
   }
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {

+ 5 - 5
panda/src/dxgsg9/dxVertexBufferContext9.cxx

@@ -26,10 +26,10 @@ TypeHandle DXVertexBufferContext9::_type_handle;
 /**
 /**
  *
  *
  */
  */
-CLP(VertexBufferContext)::
-CLP(VertexBufferContext)(CLP(GraphicsStateGuardian) *dxgsg,
-                         PreparedGraphicsObjects *pgo,
-                         GeomVertexArrayData *data) :
+DXVertexBufferContext9::
+DXVertexBufferContext9(DXGraphicsStateGuardian9 *dxgsg,
+                       PreparedGraphicsObjects *pgo,
+                       GeomVertexArrayData *data) :
   VertexBufferContext(pgo, data),
   VertexBufferContext(pgo, data),
   _vbuffer(NULL)
   _vbuffer(NULL)
 {
 {
@@ -170,7 +170,7 @@ CLP(VertexBufferContext)(CLP(GraphicsStateGuardian) *dxgsg,
  * epoch), or requeue itself on the tail of the queue (in which case the
  * epoch), or requeue itself on the tail of the queue (in which case the
  * eviction will be requested again much later).
  * eviction will be requested again much later).
  */
  */
-void CLP(VertexBufferContext)::
+void DXVertexBufferContext9::
 evict_lru() {
 evict_lru() {
   dequeue_lru();
   dequeue_lru();
 
 

+ 4 - 4
panda/src/dxgsg9/dxVertexBufferContext9.h

@@ -19,17 +19,17 @@
 #include "vertexBufferContext.h"
 #include "vertexBufferContext.h"
 #include "deletedChain.h"
 #include "deletedChain.h"
 
 
-class CLP(GraphicsStateGuardian);
+class DXGraphicsStateGuardian9;
 
 
 /**
 /**
  * Caches a GeomVertexArrayData in the DirectX device as a vertex buffer.
  * Caches a GeomVertexArrayData in the DirectX device as a vertex buffer.
  */
  */
-class EXPCL_PANDADX CLP(VertexBufferContext) : public VertexBufferContext {
+class EXPCL_PANDADX DXVertexBufferContext9 : public VertexBufferContext {
 public:
 public:
-  CLP(VertexBufferContext)(CLP(GraphicsStateGuardian) *dxgsg,
+  DXVertexBufferContext9(DXGraphicsStateGuardian9 *dxgsg,
                            PreparedGraphicsObjects *pgo,
                            PreparedGraphicsObjects *pgo,
                            GeomVertexArrayData *data);
                            GeomVertexArrayData *data);
-  ALLOC_DELETED_CHAIN(CLP(VertexBufferContext));
+  ALLOC_DELETED_CHAIN(DXVertexBufferContext9);
 
 
   virtual void evict_lru();
   virtual void evict_lru();
 
 

+ 4 - 2
panda/src/dxgsg9/wdxGraphicsBuffer9.cxx

@@ -312,16 +312,18 @@ rebuild_bitplanes() {
         case RTP_aux_float_3:
         case RTP_aux_float_3:
           {
           {
             CDWriter cdataw(_cycler, cdata, false);
             CDWriter cdataw(_cycler, cdata, false);
-            nassertr(cdata->_textures.size() == cdataw->_textures.size(), false);
             cdataw->_textures[i]._rtm_mode = RTM_none;
             cdataw->_textures[i]._rtm_mode = RTM_none;
           }
           }
+          // Creating the CDWriter invalidated the CDLockedReader.
+          cdata = CDLockedReader(_cycler);
           break;
           break;
         default:
         default:
           {
           {
             CDWriter cdataw(_cycler, cdata, false);
             CDWriter cdataw(_cycler, cdata, false);
-            nassertr(cdata->_textures.size() == cdataw->_textures.size(), false);
             cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
             cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
           }
           }
+          // Creating the CDWriter invalidated the CDLockedReader.
+          cdata = CDLockedReader(_cycler);
           break;
           break;
         }
         }
       }
       }

+ 1 - 5
panda/src/egg/eggVertex.cxx

@@ -138,11 +138,7 @@ has_uvw(const string &name) const {
 bool EggVertex::
 bool EggVertex::
 has_aux(const string &name) const {
 has_aux(const string &name) const {
   AuxMap::const_iterator xi = _aux_map.find(name);
   AuxMap::const_iterator xi = _aux_map.find(name);
-  if (xi != _aux_map.end()) {
-    EggVertexAux *aux_obj = (*xi).second;
-    return true;
-  }
-  return false;
+  return (xi != _aux_map.end());
 }
 }
 
 
 /**
 /**

+ 0 - 39
panda/src/event/asyncTask.cxx

@@ -18,10 +18,6 @@
 #include "throw_event.h"
 #include "throw_event.h"
 #include "eventParameter.h"
 #include "eventParameter.h"
 
 
-#ifdef HAVE_PYTHON
-#include "py_panda.h"
-#endif
-
 AtomicAdjust::Integer AsyncTask::_next_task_id;
 AtomicAdjust::Integer AsyncTask::_next_task_id;
 PStatCollector AsyncTask::_show_code_pcollector("App:Show code");
 PStatCollector AsyncTask::_show_code_pcollector("App:Show code");
 TypeHandle AsyncTask::_type_handle;
 TypeHandle AsyncTask::_type_handle;
@@ -48,9 +44,6 @@ AsyncTask(const string &name) :
   _total_dt(0.0),
   _total_dt(0.0),
   _num_frames(0)
   _num_frames(0)
 {
 {
-#ifdef HAVE_PYTHON
-  _python_object = NULL;
-#endif  // HAVE_PYTHON
   set_name(name);
   set_name(name);
 
 
   // Carefully copy _next_task_id and increment it so that we get a unique ID.
   // Carefully copy _next_task_id and increment it so that we get a unique ID.
@@ -68,9 +61,6 @@ AsyncTask(const string &name) :
 AsyncTask::
 AsyncTask::
 ~AsyncTask() {
 ~AsyncTask() {
   nassertv(_state == S_inactive && _manager == NULL && _chain == NULL);
   nassertv(_state == S_inactive && _manager == NULL && _chain == NULL);
-#ifdef HAVE_PYTHON
-  set_python_object(NULL);
-#endif
 }
 }
 
 
 /**
 /**
@@ -355,35 +345,6 @@ set_priority(int priority) {
   }
   }
 }
 }
 
 
-#ifdef HAVE_PYTHON
-/**
- * Specifies an arbitrary Python object that will be piggybacked on the task
- * object.
- */
-void AsyncTask::
-set_python_object(PyObject *python_object) {
-  Py_XINCREF(python_object);
-  Py_XDECREF(_python_object);
-  _python_object = python_object;
-}
-#endif  // HAVE_PYTHON
-
-#ifdef HAVE_PYTHON
-/**
- * Returns the Python object that was specified to set_python_object(), if
- * any, or None if no object was specified.
- */
-PyObject *AsyncTask::
-get_python_object() const {
-  if (_python_object != (PyObject *)NULL) {
-    Py_XINCREF(_python_object);
-    return _python_object;
-  }
-  Py_INCREF(Py_None);
-  return Py_None;
-}
-#endif  // HAVE_PYTHON
-
 /**
 /**
  *
  *
  */
  */

+ 0 - 10
panda/src/event/asyncTask.h

@@ -92,11 +92,6 @@ PUBLISHED:
   INLINE void set_done_event(const string &done_event);
   INLINE void set_done_event(const string &done_event);
   INLINE const string &get_done_event() const;
   INLINE const string &get_done_event() const;
 
 
-#ifdef HAVE_PYTHON
-  void set_python_object(PyObject *python_object);
-  PyObject *get_python_object() const;
-#endif  // HAVE_PYTHON
-
   INLINE double get_dt() const;
   INLINE double get_dt() const;
   INLINE double get_max_dt() const;
   INLINE double get_max_dt() const;
   INLINE double get_average_dt() const;
   INLINE double get_average_dt() const;
@@ -140,11 +135,6 @@ protected:
   static PStatCollector _show_code_pcollector;
   static PStatCollector _show_code_pcollector;
   PStatCollector _task_pcollector;
   PStatCollector _task_pcollector;
 
 
-private:
-#ifdef HAVE_PYTHON
-  PyObject *_python_object;
-#endif  // HAVE_PYTHON
-
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {
     return _type_handle;
     return _type_handle;

+ 0 - 34
panda/src/event/pythonTask.I

@@ -10,37 +10,3 @@
  * @author drose
  * @author drose
  * @date 2008-09-16
  * @date 2008-09-16
  */
  */
-
-/**
- * If None is passed, calls clear_delay, otherwise sets the delay time.  See
- * AsyncTask::set_delay() and AsyncTask::clear_delay().
- */
-INLINE void PythonTask::
-set_delay(PyObject *delay) {
-  if (delay == Py_None) {
-    AsyncTask::clear_delay();
-    return;
-  }
-
-  PyObject *value = PyNumber_Float(delay);
-  if (value == NULL) {
-    return;
-  }
-
-  AsyncTask::set_delay(PyFloat_AS_DOUBLE(value));
-  Py_DECREF(value);
-}
-
-/**
- * Returns the delay time if set, None otherwise.  See AsyncTask::has_delay()
- * and AsyncTask::get_delay().
- */
-INLINE PyObject *PythonTask::
-get_delay() const {
-  if (AsyncTask::has_delay()) {
-    return PyFloat_FromDouble(AsyncTask::get_delay());
-  } else {
-    Py_INCREF(Py_None);
-    return Py_None;
-  }
-}

+ 24 - 18
panda/src/event/pythonTask.cxx

@@ -18,12 +18,9 @@
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
 #include "py_panda.h"
 #include "py_panda.h"
 
 
-TypeHandle PythonTask::_type_handle;
+#include "pythonThread.h"
 
 
-Configure(config_pythonTask);
-ConfigureFn(config_pythonTask) {
-  PythonTask::init_type();
-}
+TypeHandle PythonTask::_type_handle;
 
 
 #ifndef CPPPARSER
 #ifndef CPPPARSER
 extern struct Dtool_PyTypedObject Dtool_TypedReferenceCount;
 extern struct Dtool_PyTypedObject Dtool_TypedReferenceCount;
@@ -188,6 +185,19 @@ get_upon_death() {
  */
  */
 void PythonTask::
 void PythonTask::
 set_owner(PyObject *owner) {
 set_owner(PyObject *owner) {
+#ifndef NDEBUG
+  if (owner != Py_None) {
+    PyObject *add = PyObject_GetAttrString(owner, "_addTask");
+    PyObject *clear = PyObject_GetAttrString(owner, "_clearTask");
+
+    if (add == NULL || !PyCallable_Check(add) ||
+        clear == NULL || !PyCallable_Check(clear)) {
+      Dtool_Raise_TypeError("owner object should have _addTask and _clearTask methods");
+      return;
+    }
+  }
+#endif
+
   if (_owner != NULL && _owner != Py_None && _state != S_inactive) {
   if (_owner != NULL && _owner != Py_None && _state != S_inactive) {
     unregister_from_owner();
     unregister_from_owner();
   }
   }
@@ -391,8 +401,7 @@ do_python_task() {
   if (_generator == (PyObject *)NULL) {
   if (_generator == (PyObject *)NULL) {
     // We are calling the function directly.
     // We are calling the function directly.
     PyObject *args = get_args();
     PyObject *args = get_args();
-    result =
-      Thread::get_current_thread()->call_python_func(_function, args);
+    result = PythonThread::call_python_func(_function, args);
     Py_DECREF(args);
     Py_DECREF(args);
 
 
 #ifdef PyGen_Check
 #ifdef PyGen_Check
@@ -494,10 +503,16 @@ do_python_task() {
   ostringstream strm;
   ostringstream strm;
 #if PY_MAJOR_VERSION >= 3
 #if PY_MAJOR_VERSION >= 3
   PyObject *str = PyObject_ASCII(result);
   PyObject *str = PyObject_ASCII(result);
+  if (str == NULL) {
+    str = PyUnicode_FromString("<repr error>");
+  }
   strm
   strm
     << *this << " returned " << PyUnicode_AsUTF8(str);
     << *this << " returned " << PyUnicode_AsUTF8(str);
 #else
 #else
   PyObject *str = PyObject_Repr(result);
   PyObject *str = PyObject_Repr(result);
+  if (str == NULL) {
+    str = PyString_FromString("<repr error>");
+  }
   strm
   strm
     << *this << " returned " << PyString_AsString(str);
     << *this << " returned " << PyString_AsString(str);
 #endif
 #endif
@@ -606,18 +621,9 @@ call_owner_method(const char *method_name) {
   if (_owner != Py_None) {
   if (_owner != Py_None) {
     PyObject *func = PyObject_GetAttrString(_owner, (char *)method_name);
     PyObject *func = PyObject_GetAttrString(_owner, (char *)method_name);
     if (func == (PyObject *)NULL) {
     if (func == (PyObject *)NULL) {
-#if PY_MAJOR_VERSION >= 3
-      PyObject *str = PyObject_ASCII(_owner);
       task_cat.error()
       task_cat.error()
-        << "Owner object " << PyUnicode_AsUTF8(str) << " added to "
-        << *this << " has no method " << method_name << "().\n";
-#else
-      PyObject *str = PyObject_Repr(_owner);
-      task_cat.error()
-        << "Owner object " << PyString_AsString(str) << " added to "
-        << *this << " has no method " << method_name << "().\n";
-#endif
-      Py_DECREF(str);
+        << "Owner object added to " << *this << " has no method "
+        << method_name << "().\n";
 
 
     } else {
     } else {
       call_function(func);
       call_function(func);

+ 2 - 5
panda/src/event/pythonTask.h

@@ -50,9 +50,6 @@ PUBLISHED:
   int __traverse__(visitproc visit, void *arg);
   int __traverse__(visitproc visit, void *arg);
   int __clear__();
   int __clear__();
 
 
-  INLINE void set_delay(PyObject *delay);
-  INLINE PyObject *get_delay() const;
-
 PUBLISHED:
 PUBLISHED:
   // The name of this task.
   // The name of this task.
   MAKE_PROPERTY(name, get_name, set_name);
   MAKE_PROPERTY(name, get_name, set_name);
@@ -72,10 +69,10 @@ PUBLISHED:
   MAKE_PROPERTY(wakeTime, get_wake_time);
   MAKE_PROPERTY(wakeTime, get_wake_time);
 
 
   // The delay value that has been set on this task, if any, or None.
   // The delay value that has been set on this task, if any, or None.
-  MAKE_PROPERTY(delay_time, get_delay, set_delay);
+  MAKE_PROPERTY2(delay_time, has_delay, get_delay, set_delay, clear_delay);
 
 
   // Alias of delay_time.
   // Alias of delay_time.
-  MAKE_PROPERTY(delayTime, get_delay, set_delay);
+  MAKE_PROPERTY2(delayTime, has_delay, get_delay, set_delay, clear_delay);
 
 
   // The number of frames that have elapsed since the task was started,
   // The number of frames that have elapsed since the task was started,
   // according to the task manager's clock.
   // according to the task manager's clock.

+ 1 - 1
panda/src/express/memoryInfo.cxx

@@ -108,7 +108,7 @@ determine_dynamic_type() {
         return;
         return;
       }
       }
 
 
-      TypeHandle orig_type = _dynamic_type;
+      //TypeHandle orig_type = _dynamic_type;
       update_type_handle(_dynamic_type, got_type);
       update_type_handle(_dynamic_type, got_type);
     }
     }
   }
   }

+ 2 - 2
panda/src/express/nodeReferenceCount.I

@@ -129,7 +129,7 @@ node_ref() const {
 #endif
 #endif
 
 
   ref();
   ref();
-  AtomicAdjust::inc(((NodeReferenceCount *)this)->_node_ref_count);
+  AtomicAdjust::inc(_node_ref_count);
 }
 }
 
 
 /**
 /**
@@ -174,7 +174,7 @@ node_unref_only() const {
   // you can't use PointerTo's?
   // you can't use PointerTo's?
   nassertv(_node_ref_count > 0);
   nassertv(_node_ref_count > 0);
 
 
-  AtomicAdjust::dec(((NodeReferenceCount *)this)->_node_ref_count);
+  AtomicAdjust::dec(_node_ref_count);
 }
 }
 
 
 /**
 /**

+ 2 - 3
panda/src/express/nodeReferenceCount.h

@@ -42,14 +42,13 @@ PUBLISHED:
   INLINE void node_ref() const;
   INLINE void node_ref() const;
   INLINE bool node_unref() const;
   INLINE bool node_unref() const;
   INLINE bool test_ref_count_integrity() const;
   INLINE bool test_ref_count_integrity() const;
-
-protected:
   INLINE void node_unref_only() const;
   INLINE void node_unref_only() const;
 
 
+protected:
   bool do_test_ref_count_integrity() const;
   bool do_test_ref_count_integrity() const;
 
 
 private:
 private:
-  AtomicAdjust::Integer _node_ref_count;
+  mutable AtomicAdjust::Integer _node_ref_count;
 
 
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {

+ 0 - 1
panda/src/express/ordered_vector.T

@@ -280,7 +280,6 @@ TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE ordered_vector<Key, Com
 r_count(TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR first,
 r_count(TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR first,
         TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR last,
         TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR last,
         const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
         const TYPENAME ordered_vector<Key, Compare, Vector>::KEY_TYPE &key) const {
-  typedef pair<TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR, TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR> pair_type;
 
 
   if (first == last) {
   if (first == last) {
     // The list is empty; the key is not on the list.
     // The list is empty; the key is not on the list.

+ 0 - 4
panda/src/express/pointerToArray.h

@@ -102,11 +102,9 @@ PUBLISHED:
   INLINE int get_node_ref_count() const;
   INLINE int get_node_ref_count() const;
 
 
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
-#if PY_VERSION_HEX >= 0x02060000
   EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags));
   EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags));
   EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
   EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
 #endif
 #endif
-#endif
 
 
 #else  // CPPPARSER
 #else  // CPPPARSER
   // This is the actual, complete interface.
   // This is the actual, complete interface.
@@ -257,11 +255,9 @@ PUBLISHED:
   INLINE int get_node_ref_count() const;
   INLINE int get_node_ref_count() const;
 
 
 #ifdef HAVE_PYTHON
 #ifdef HAVE_PYTHON
-#if PY_VERSION_HEX >= 0x02060000
   EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const);
   EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const);
   EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
   EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
 #endif
 #endif
-#endif
 
 
 #else  // CPPPARSER
 #else  // CPPPARSER
   // This is the actual, complete interface.
   // This is the actual, complete interface.

+ 12 - 6
panda/src/express/pointerToArray_ext.I

@@ -175,7 +175,6 @@ __getitem__(size_t n) const {
   return (*this->_this)[n];
   return (*this->_this)[n];
 }
 }
 
 
-#if PY_VERSION_HEX >= 0x02060000
 /**
 /**
  * This is used to implement the buffer protocol, in order to allow efficient
  * This is used to implement the buffer protocol, in order to allow efficient
  * access to the array data through a Python multiview object.
  * access to the array data through a Python multiview object.
@@ -183,7 +182,7 @@ __getitem__(size_t n) const {
 template<class Element>
 template<class Element>
 INLINE int Extension<PointerToArray<Element> >::
 INLINE int Extension<PointerToArray<Element> >::
 __getbuffer__(PyObject *self, Py_buffer *view, int flags) {
 __getbuffer__(PyObject *self, Py_buffer *view, int flags) {
-
+#if PY_VERSION_HEX >= 0x02060000
   const char *format = get_format_code(Element);
   const char *format = get_format_code(Element);
   if (format == NULL) {
   if (format == NULL) {
     // Not supported.
     // Not supported.
@@ -222,6 +221,9 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) {
   view->internal = (void*) this->_this;
   view->internal = (void*) this->_this;
 
 
   return 0;
   return 0;
+#else
+  return -1;
+#endif
 }
 }
 
 
 /**
 /**
@@ -230,13 +232,14 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) {
 template<class Element>
 template<class Element>
 INLINE void Extension<PointerToArray<Element> >::
 INLINE void Extension<PointerToArray<Element> >::
 __releasebuffer__(PyObject *self, Py_buffer *view) const {
 __releasebuffer__(PyObject *self, Py_buffer *view) const {
+#if PY_VERSION_HEX >= 0x02060000
   // Note: PyBuffer_Release automatically decrements view->obj.
   // Note: PyBuffer_Release automatically decrements view->obj.
-
   if (view->internal != NULL) {
   if (view->internal != NULL) {
     // Oh, right, let's not forget to unref this.
     // Oh, right, let's not forget to unref this.
     unref_delete((const PointerToArray<Element> *)view->internal);
     unref_delete((const PointerToArray<Element> *)view->internal);
     view->internal = NULL;
     view->internal = NULL;
   }
   }
+#endif
 }
 }
 
 
 /**
 /**
@@ -246,7 +249,7 @@ __releasebuffer__(PyObject *self, Py_buffer *view) const {
 template<class Element>
 template<class Element>
 INLINE int Extension<ConstPointerToArray<Element> >::
 INLINE int Extension<ConstPointerToArray<Element> >::
 __getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
 __getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
-
+#if PY_VERSION_HEX >= 0x02060000
   if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
   if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
     PyErr_SetString(PyExc_BufferError,
     PyErr_SetString(PyExc_BufferError,
                     "Object is not writable.");
                     "Object is not writable.");
@@ -291,6 +294,9 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
   view->internal = (void*) this->_this;
   view->internal = (void*) this->_this;
 
 
   return 0;
   return 0;
+#else
+  return -1;
+#endif
 }
 }
 
 
 /**
 /**
@@ -299,12 +305,12 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
 template<class Element>
 template<class Element>
 INLINE void Extension<ConstPointerToArray<Element> >::
 INLINE void Extension<ConstPointerToArray<Element> >::
 __releasebuffer__(PyObject *self, Py_buffer *view) const {
 __releasebuffer__(PyObject *self, Py_buffer *view) const {
+#if PY_VERSION_HEX >= 0x02060000
   // Note: PyBuffer_Release automatically decrements obj->view.
   // Note: PyBuffer_Release automatically decrements obj->view.
-
   if (view->internal != NULL) {
   if (view->internal != NULL) {
     // Oh, right, let's not forget to unref this.
     // Oh, right, let's not forget to unref this.
     unref_delete((const PointerToArray<Element> *)view->internal);
     unref_delete((const PointerToArray<Element> *)view->internal);
     view->internal = NULL;
     view->internal = NULL;
   }
   }
+#endif
 }
 }
-#endif  // PY_VERSION_HEX

+ 0 - 4
panda/src/express/pointerToArray_ext.h

@@ -35,10 +35,8 @@ public:
   INLINE const Element &__getitem__(size_t n) const;
   INLINE const Element &__getitem__(size_t n) const;
   INLINE void __setitem__(size_t n, const Element &value);
   INLINE void __setitem__(size_t n, const Element &value);
 
 
-#if PY_VERSION_HEX >= 0x02060000
   INLINE int __getbuffer__(PyObject *self, Py_buffer *view, int flags);
   INLINE int __getbuffer__(PyObject *self, Py_buffer *view, int flags);
   INLINE void __releasebuffer__(PyObject *self, Py_buffer *view) const;
   INLINE void __releasebuffer__(PyObject *self, Py_buffer *view) const;
-#endif
 };
 };
 
 
 /**
 /**
@@ -55,10 +53,8 @@ public:
 
 
   INLINE const Element &__getitem__(size_t n) const;
   INLINE const Element &__getitem__(size_t n) const;
 
 
-#if PY_VERSION_HEX >= 0x02060000
   INLINE int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const;
   INLINE int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const;
   INLINE void __releasebuffer__(PyObject *self, Py_buffer *view) const;
   INLINE void __releasebuffer__(PyObject *self, Py_buffer *view) const;
-#endif
 };
 };
 
 
 #ifdef _MSC_VER
 #ifdef _MSC_VER

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác