Sfoglia il codice sorgente

Merge branch 'master' into vulkan

rdb 9 anni fa
parent
commit
861d5d438e
100 ha cambiato i file con 836 aggiunte e 822 eliminazioni
  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
  */
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
 #ifndef _AIBEHAVIORS_H
 #define _AIBEHAVIORS_H
 

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

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

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

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

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

@@ -11,11 +11,6 @@
  * @date 2009-09-08
  */
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
-
 #ifndef _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();
   LVecBase3 avoidance(0.0, 0.0, 0.0);
   double distance = 0x7fff ;
-  double expanded_radius;
+  double expanded_radius = 0;
   LVecBase3 to_obstacle;
   LVecBase3 prev_avoidance;
   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();
   PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
   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());
     direction.normalize();
     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
  * fields, all of which are of the same type.
  */
-class EXPCL_DIRECT DCArrayParameter : public DCParameter {
+class DCArrayParameter : public DCParameter {
 public:
   DCArrayParameter(DCParameter *element_type,
                    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
  * implemented as a remote procedure method.
  */
-class EXPCL_DIRECT DCAtomicField : public DCField {
+class DCAtomicField : public DCField {
 public:
   DCAtomicField(const string &name, DCClass *dclass, bool bogus_field);
   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.
  */
-class EXPCL_DIRECT DCClass : public DCDeclaration {
+class DCClass : public DCDeclaration {
 public:
   DCClass(DCFile *dc_file, const string &name,
           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 means that all the fields of the class get packed into the message.
  */
-class EXPCL_DIRECT DCClassParameter : public DCParameter {
+class DCClassParameter : public DCParameter {
 public:
   DCClassParameter(const DCClass *dclass);
   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
  * together so they can be ordered correctly on output.
  */
-class EXPCL_DIRECT DCDeclaration {
+class DCDeclaration {
 public:
   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.
  */
-class EXPCL_DIRECT DCField : public DCPackerInterface, public DCKeywordList {
+class DCField : public DCPackerInterface, public DCKeywordList {
 public:
   DCField();
   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
  * a .dc file.
  */
-class EXPCL_DIRECT DCFile {
+class DCFile {
 PUBLISHED:
   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
  * "broadcast" or "airecv".
  */
-class EXPCL_DIRECT DCKeyword : public DCDeclaration {
+class DCKeyword : public DCDeclaration {
 public:
   DCKeyword(const string &name, int historical_flag = ~0);
   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
  * field.
  */
-class EXPCL_DIRECT DCKeywordList {
+class DCKeywordList {
 public:
   DCKeywordList();
   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
  * will often be treated as a unit.
  */
-class EXPCL_DIRECT DCMolecularField : public DCField {
+class DCMolecularField : public DCField {
 public:
   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.
  */
-class EXPCL_DIRECT DCPackData {
+class DCPackData {
 PUBLISHED:
   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
  * examples of using this class.
  */
-class EXPCL_DIRECT DCPacker {
+class DCPacker {
 PUBLISHED:
   DCPacker();
   ~DCPacker();
@@ -216,7 +216,7 @@ private:
   const DCPackerCatalog *_catalog;
   const DCPackerCatalog::LiveCatalog *_live_catalog;
 
-  class EXPCL_DIRECT StackElement {
+  class StackElement {
   public:
     // As an optimization, we implement operator new and delete here to
     // 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
  * so it must not be deleted.
  */
-class EXPCL_DIRECT DCPackerCatalog {
+class DCPackerCatalog {
 private:
   DCPackerCatalog(const DCPackerInterface *root);
   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
  * wouldn't normally call these directly.
  */
-class EXPCL_DIRECT DCPackerInterface {
+class DCPackerInterface {
 public:
   DCPackerInterface(const string &name = string());
   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
  * properties as the referenced type, but a different name.
  */
-class EXPCL_DIRECT DCParameter : public DCField {
+class DCParameter : public DCField {
 protected:
   DCParameter();
   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
  * represents a fixed-point numeric convention).
  */
-class EXPCL_DIRECT DCSimpleParameter : public DCParameter {
+class DCSimpleParameter : public DCParameter {
 public:
   DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
   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
  * field read.
  */
-class EXPCL_DIRECT DCSwitch : public DCDeclaration {
+class DCSwitch : public DCDeclaration {
 public:
   DCSwitch(const string &name, DCField *key_parameter);
   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
  * appropriate fields of the switch into the message.
  */
-class EXPCL_DIRECT DCSwitchParameter : public DCParameter {
+class DCSwitchParameter : public DCParameter {
 public:
   DCSwitchParameter(const DCSwitch *dswitch);
   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
  * particular type to a new name, just like a C typedef.
  */
-class EXPCL_DIRECT DCTypedef : public DCDeclaration {
+class DCTypedef : public DCDeclaration {
 public:
   DCTypedef(DCParameter *parameter, bool implicit = false);
   DCTypedef(const string &name);

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

@@ -402,8 +402,28 @@ send_datagram(const Datagram &dg) {
   }
 
 #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
 
 #ifdef HAVE_NET

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

@@ -33,7 +33,7 @@ class FileSpec:
         if st is None:
             st = os.stat(pathname.toOsSpecific())
         self.size = st.st_size
-        self.timestamp = st.st_mtime
+        self.timestamp = int(st.st_mtime)
 
         self.readHash(pathname)
 
@@ -124,7 +124,7 @@ class FileSpec:
                 self.__correctHash(packageDir, pathname, st, notify)
             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
             # file passes.
             if notify:
@@ -198,7 +198,7 @@ class FileSpec:
         # 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
         # successfully next time.
-        if st.st_mtime != self.timestamp:
+        if int(st.st_mtime) != self.timestamp:
             self.__updateTimestamp(pathname, st)
 
         return True
@@ -219,7 +219,7 @@ class FileSpec:
         if notify:
             notify.info("Correcting timestamp of %s to %d (%s)" % (
                 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):
         """ 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 "windowHandle.h"
 
-#include <Python.h>
-
 class P3DSession;
 
 /**

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

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

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

@@ -984,7 +984,10 @@ class Freezer:
             try:
                 self.__loadModule(mdef)
             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
         # 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)
 
         thread = core.PythonThread(threadFunc, [threadId], name, name)
-        thread.setPythonData(threadId)
+        thread.setPythonIndex(threadId)
         _threads[threadId] = (thread, {}, None)
 
         thread.start(core.TPNormal, False)
@@ -121,7 +121,7 @@ def _add_thread(thread, wrapper):
         threadId = _nextThreadId
         _nextThreadId += 1
 
-        thread.setPythonData(threadId)
+        thread.setPythonIndex(threadId)
         _threads[threadId] = (thread, {}, wrapper)
         return threadId
 
@@ -133,8 +133,8 @@ def _get_thread_wrapper(thread, wrapperClass):
     is not one, creates an instance of the indicated wrapperClass
     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.
 
         global _nextThreadId
@@ -143,7 +143,7 @@ def _get_thread_wrapper(thread, wrapperClass):
             threadId = _nextThreadId
             _nextThreadId += 1
 
-            thread.setPythonData(threadId)
+            thread.setPythonIndex(threadId)
             wrapper = wrapperClass(thread, threadId)
             _threads[threadId] = (thread, {}, wrapper)
             return wrapper
@@ -169,8 +169,8 @@ def _get_thread_locals(thread, i):
     """ Returns the locals dictionary for the indicated thread.  If
     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.
 
         global _nextThreadId
@@ -179,7 +179,7 @@ def _get_thread_locals(thread, i):
             threadId = _nextThreadId
             _nextThreadId += 1
 
-            thread.setPythonData(threadId)
+            thread.setPythonIndex(threadId)
             locals = {}
             _threads[threadId] = (thread, locals, None)
             return locals.setdefault(i, {})
@@ -205,9 +205,9 @@ def _remove_thread_id(threadId):
     _threadsLock.acquire()
     try:
         thread, locals, wrapper = _threads[threadId]
-        assert thread.getPythonData() == threadId
+        assert thread.getPythonIndex() == threadId
         del _threads[threadId]
-        thread.setPythonData(None)
+        thread.setPythonIndex(-1)
 
     finally:
         _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
 * Fix crashes with pbuffers on Intel cards on Windows
 * 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  ------------------------
 

+ 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?
       int pnum = -1;
-      bool va_args = false;
 
       if (ident == "__VA_ARGS__") {
-        va_args = true;
         // C99-style variadics, ie.  #define macro(...) __VA_ARGS__
         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);
           if (mi != _manifests.end()) {
             const CPPManifest *manifest = (*mi).second;
-            expand_manifest_inline(expr, q, p, (*mi).second);
+            expand_manifest_inline(expr, q, p, manifest);
             manifest_found = true;
 
           } else if (expand_undefined && ident != "true" && ident != "false") {
@@ -1192,8 +1192,6 @@ skip_c_comment(int c) {
 
   } else {
     CPPFile first_file = get_file();
-    int first_line_number = get_line_number();
-    int first_col_number = get_col_number() - 2;
 
     while (c != EOF) {
       if (c == '*') {
@@ -1816,8 +1814,9 @@ get_identifier(int c) {
       type = CPPExpression::T_u16string;
     } else if (name == "U") {
       type = CPPExpression::T_u32string;
+    } else {
+      type = CPPExpression::T_string;
     }
-
     get();
     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(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;
 }

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

@@ -70,23 +70,25 @@
 #else
 // #pragma message("VC 6.0")
 #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
 // 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')
 #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
-# define NODEFAULT  default: __assume(0);   // special VC keyword
+#define NODEFAULT
 #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

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

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

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

@@ -323,7 +323,7 @@ seekoff(streamoff off, ios_seekdir dir, ios_openmode which) {
       // Posix case.
       {
         off_t li = lseek(_fd, off, SEEK_END);
-        if (li == (size_t)-1) {
+        if (li == (off_t)-1) {
           return -1;
         }
         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) &&
           isExportThisRun(object->_itype._cpptype)) {
         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 (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 = "
               << object->_itype._cpptype->get_local_name(&parser)
               << "::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 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";
     } else {
       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);
 
   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;
   }
 
@@ -4196,7 +4203,7 @@ write_function_forset(ostream &out,
     return;
   }
 
-  FunctionRemap *remap;
+  FunctionRemap *remap = NULL;
   std::set<FunctionRemap *>::iterator sii;
 
   bool all_nonconst = false;
@@ -7010,7 +7017,7 @@ DoesInheritFromIsClass(const CPPStructType *inclass, const std::string &name) {
 
  */
 bool InterfaceMakerPythonNative::
-HasAGetClassTypeFunction(CPPType *type) {
+has_get_class_type_function(CPPType *type) {
   while (type->get_subtype() == CPPDeclaration::ST_typedef) {
     type = type->as_typedef_type()->_type;
   }
@@ -7025,6 +7032,43 @@ HasAGetClassTypeFunction(CPPType *type) {
   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
  * 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 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);
-  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 NeedsAReprFunction(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 "panda_getopt_long.h"
 #include "preprocess_argv.h"
-#include "pystub.h"
 #include <time.h>
 
 CPPParser parser;
@@ -306,9 +305,6 @@ predefine_macro(CPPParser& parser, const string& inoption) {
 
 int
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   preprocess_argv(argc, argv);
   string command_line;
   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.
-      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 (is_seq && !TypeManager::is_integer(ftype->_parameters->_parameters[0]->_type)) {
           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) {
       CPPInstance *function = (*fi);
       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;
         break;
       }

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

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

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

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

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

@@ -31,7 +31,7 @@ public:
  * extended should create a specialization of this class template.
  */
 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) {
+  // 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);
+#else
+  return (value > LONG_MAX)
+    ? PyLong_FromUnsignedLongLong(value)
+    : PyInt_FromLong((long)value);
+#endif
 }
 
 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);
   bool result;
   switch (op) {
+  NODEFAULT
   case Py_LT:
     result = (cmpval < 0);
     break;
@@ -833,6 +834,7 @@ PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op) {
     break;
   case Py_GE:
     result = (cmpval >= 0);
+    break;
   }
   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
-// 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..
 #ifdef NDEBUG

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

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

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

@@ -19,16 +19,28 @@
  */
 void ConfigVariableFilename::
 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 {
   TAU_PROFILE("const string &ConfigVariableString::get_value() const", " ", TAU_USER);
   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;
 }

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

@@ -12,3 +12,24 @@
  */
 
 #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 void set_word(size_t n, const string &value);
 
+private:
+  void reload_cache();
+
 private:
   AtomicAdjust::Integer _local_modified;
   string _cache;

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

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

File diff suppressed because it is too large
+ 136 - 126
makepanda/makepanda.py


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

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

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

@@ -3,6 +3,7 @@
 #include "animBundleNode.cxx"
 #include "animChannel.cxx"
 #include "animChannelBase.cxx"
+#include "animChannelFixed.cxx"
 #include "animChannelMatrixDynamic.cxx"
 #include "animChannelMatrixFixed.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
   // parent nodes immediately.
   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);
     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];
 
-  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[1] = int((region._dimensions[1] * x_size) + 0.5);
   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_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
  * 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
   // DisplayRegions.
-  typedef pair<NodePath, int> CullKey;
   typedef pmap<CullKey, DisplayRegion *> AlreadyCulled;
   AlreadyCulled already_culled;
 
@@ -1390,10 +1406,13 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
         if (dr != (DisplayRegion *)NULL) {
           DisplayRegionPipelineReader *dr_reader =
             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) {
             // We have not used this camera already in this thread.  Perform
             // 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
         // 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);
 
           if (display_cat.is_spam()) {
@@ -1528,8 +1547,8 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
         if (_auto_flip) {
 #ifdef DO_PSTATS
           // 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
 
@@ -1541,7 +1560,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
               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();
             }
           }

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

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

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

@@ -238,6 +238,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
   _supports_basic_shaders = false;
   _supports_geometry_shaders = false;
   _supports_tessellation_shaders = false;
+  _supports_compute_shaders = false;
   _supports_glsl = false;
   _supports_hlsl = false;
   _supports_framebuffer_multisample = false;
@@ -2065,8 +2066,6 @@ flush_timer_queries() {
 
     _last_num_queried = first;
 
-    int frame_index = ClockObject::get_global_clock()->get_frame_count();
-
     for (int i = 0; i < first; ++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 {
   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),
   _shader_skinning(false)
 {
-  _render_mode = (const RenderModeAttrib *)
-    state->get_attrib(RenderModeAttrib::get_class_slot());
-
   if (!get_gsg()->get_runtime_color_scale()) {
     // We might need to munge the colors.
     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.
     if ((unsupported_bits & Geom::GR_composite_bits) != 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();
 
       // 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.
     if ((unsupported_bits & Geom::GR_composite_bits) != 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();
 
       // Decomposing might produce an indexed Geom, so re-check the
@@ -267,10 +264,6 @@ int StandardMunger::
 compare_to_impl(const GeomMunger *other) const {
   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) {
     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 CPT(RenderState) munge_state_impl(const RenderState *state);
 
-  INLINE RenderModeAttrib::Mode get_render_mode() const;
-
 private:
   int _num_components;
   NumericType _numeric_type;
   Contents _contents;
-  CPT(RenderModeAttrib) _render_mode;
 
   bool _munge_color;
   bool _munge_color_scale;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -403,10 +403,35 @@ extract_texture_data(Texture *tex) {
  */
 ShaderContext *DXGraphicsStateGuardian9::
 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
-  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
+
+  default:
+    dxgsg9_cat.error()
+      << "Tried to load shader with unsupported shader language!\n";
+    return NULL;
+  }
+
   return NULL;
 }
 
@@ -415,7 +440,7 @@ prepare_shader(Shader *se) {
  */
 void DXGraphicsStateGuardian9::
 release_shader(ShaderContext *sc) {
-  CLP(ShaderContext) *gsc = DCAST(CLP(ShaderContext), sc);
+  DXShaderContext9 *gsc = DCAST(DXShaderContext9, sc);
   delete gsc;
 }
 
@@ -429,9 +454,9 @@ release_shader(ShaderContext *sc) {
  * This function should not be called directly to prepare a buffer.  Instead,
  * call Geom::prepare().
  */
-VertexBufferContext *CLP(GraphicsStateGuardian)::
+VertexBufferContext *DXGraphicsStateGuardian9::
 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;
   D3DPOOL pool;
@@ -458,7 +483,7 @@ prepare_vertex_buffer(GeomVertexArrayData *data) {
 
   if (!FAILED(hr)) {
     #if 0
-    if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
+    if (dxgsg9_cat.is_debug() && DXdebug_buffers9) {
       dxgsg9_cat.debug()
         << "creating vertex buffer " << dvbc->_vbuffer << ": "
         << 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
  * vertex buffer for rendering.
  */
-bool CLP(GraphicsStateGuardian)::
+bool DXGraphicsStateGuardian9::
 apply_vertex_buffer(VertexBufferContext *vbc,
                     const GeomVertexArrayDataHandle *reader, bool force ) {
 
-  CLP(VertexBufferContext) *dvbc = DCAST(CLP(VertexBufferContext), vbc);
+  DXVertexBufferContext9 *dvbc = DCAST(DXVertexBufferContext9, vbc);
 
   if (dvbc->was_modified(reader)) {
     int num_bytes = reader->get_data_size_bytes();
     #if 0
-    if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
+    if (dxgsg9_cat.is_debug() && DXdebug_buffers9) {
       dxgsg9_cat.debug()
         << "copying " << num_bytes
         << " 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
  * let the Data destruct).
  */
-void CLP(GraphicsStateGuardian)::
+void DXGraphicsStateGuardian9::
 release_vertex_buffer(VertexBufferContext *vbc) {
 
-  CLP(VertexBufferContext) *dvbc = DCAST(CLP(VertexBufferContext), vbc);
+  DXVertexBufferContext9 *dvbc = DCAST(DXVertexBufferContext9, vbc);
 
   #if 0
-  if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) {
+  if (dxgsg9_cat.is_debug() && DXdebug_buffers9) {
     dxgsg9_cat.debug()
       << "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
  * not currently available.
  */
-bool CLP(GraphicsStateGuardian)::
-setup_array_data(CLP(VertexBufferContext)*& dvbc,
+bool DXGraphicsStateGuardian9::
+setup_array_data(DXVertexBufferContext9*& dvbc,
                  const GeomVertexArrayDataHandle* array_reader,
                  bool force) {
 
@@ -587,7 +612,7 @@ setup_array_data(CLP(VertexBufferContext)*& dvbc,
     return false;
   }
 
-  dvbc = (CLP(VertexBufferContext)*)vbc;
+  dvbc = (DXVertexBufferContext9*)vbc;
   return true;
 }
 
@@ -1028,17 +1053,17 @@ end_scene() {
   if (_vertex_array_shader_context != 0) {
     _vertex_array_shader_context->disable_shader_vertex_arrays(this);
     _vertex_array_shader = (Shader *)NULL;
-    _vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
+    _vertex_array_shader_context = (DXShaderContext9 *)NULL;
   }
   if (_texture_binding_shader_context != 0) {
     _texture_binding_shader_context->disable_shader_texture_bindings(this);
     _texture_binding_shader = (Shader *)NULL;
-    _texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
+    _texture_binding_shader_context = (DXShaderContext9 *)NULL;
   }
   if (_current_shader_context != 0) {
     _current_shader_context->unbind(this);
     _current_shader = (Shader *)NULL;
-    _current_shader_context = (CLP(ShaderContext) *)NULL;
+    _current_shader_context = (DXShaderContext9 *)NULL;
   }
 
   _dlights.clear();
@@ -1242,7 +1267,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
  * pipeline is about to be used - dxShaderContexts are responsible for setting
  * up their own vertex arrays.
  */
-bool CLP(GraphicsStateGuardian)::
+bool DXGraphicsStateGuardian9::
 update_standard_vertex_arrays(bool force) {
 
   int fvf = 0;
@@ -1257,7 +1282,7 @@ update_standard_vertex_arrays(bool force) {
     }
 
     // Get the vertex buffer for this array.
-    CLP(VertexBufferContext)* dvbc;
+    DXVertexBufferContext9* dvbc;
     if (!setup_array_data(dvbc, array_reader, force)) {
       dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
       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."
  * Called only from begin_draw_primitives.
  */
-void CLP(GraphicsStateGuardian)::
+void DXGraphicsStateGuardian9::
 disable_standard_vertex_arrays() {
   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_indexed_other |
     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
 
@@ -2383,7 +2409,7 @@ reset() {
   // OVERRIDE SUPPORT SINCE IT DOES NOT WORK WELL
   _screen->_supports_automatic_mipmap_generation = false;
 
-  this -> reset_render_states ( );
+  reset_render_states();
 
   _max_vertices_per_array = d3d_caps.MaxVertexIndex;
   _max_vertices_per_primitive = d3d_caps.MaxPrimitiveCount;
@@ -2646,11 +2672,11 @@ reset() {
   set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD);
 
   _current_shader = (Shader *)NULL;
-  _current_shader_context = (CLP(ShaderContext) *)NULL;
+  _current_shader_context = (DXShaderContext9 *)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_context = (CLP(ShaderContext) *)NULL;
+  _texture_binding_shader_context = (DXShaderContext9 *)NULL;
 
   PRINT_REFCNT(dxgsg9, _d3d_device);
 
@@ -2775,13 +2801,13 @@ do_issue_alpha_test() {
 void DXGraphicsStateGuardian9::
 do_issue_shader() {
 
-  CLP(ShaderContext) *context = 0;
+  DXShaderContext9 *context = 0;
   Shader *shader = 0;
   if (_target_shader) {
     shader = (Shader *)(_target_shader->get_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)) {
@@ -2819,7 +2845,8 @@ do_issue_shader() {
  */
 void DXGraphicsStateGuardian9::
 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();
 
   switch (mode) {
@@ -3395,6 +3422,8 @@ bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
 D3DFORMAT DXGraphicsStateGuardian9::
 get_index_type(Geom::NumericType numeric_type) {
   switch (numeric_type) {
+  // NT_uint8 is automatically promoted to uint16.
+  case Geom::NT_uint8:
   case Geom::NT_uint16:
     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);
     if (FAILED(hr) && hr != D3DERR_DEVICELOST) {
       return hr;

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

@@ -79,7 +79,7 @@ public:
                            bool force);
   virtual void release_vertex_buffer(VertexBufferContext *vbc);
 
-  bool setup_array_data(CLP(VertexBufferContext)*& vbc,
+  bool setup_array_data(DXVertexBufferContext9 *&vbc,
                         const GeomVertexArrayDataHandle* data,
                         bool force);
 
@@ -295,12 +295,12 @@ protected:
   CullFaceAttrib::Mode _cull_face_mode;
   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;
 

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

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

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

@@ -41,7 +41,7 @@ public:
   }
   static void init_type() {
     OcclusionQueryContext::init_type();
-    register_type(_type_handle, CLASSPREFIX_QUOTED "OcclusionQueryContext",
+    register_type(_type_handle, "DXOcclusionQueryContext9",
                   OcclusionQueryContext::get_class_type());
   }
   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
  * languages are compiled into panda.
  */
-INLINE bool CLP(ShaderContext)::
+INLINE bool DXShaderContext9::
 valid(GSG *gsg) {
 #ifdef HAVE_CG
   return (_cg_program != 0);

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

@@ -28,13 +28,13 @@
 
 #define DEBUG_SHADER 0
 
-TypeHandle CLP(ShaderContext)::_type_handle;
+TypeHandle DXShaderContext9::_type_handle;
 
 /**
  * xyz
  */
-CLP(ShaderContext)::
-CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
+DXShaderContext9::
+DXShaderContext9(Shader *s, GSG *gsg) : ShaderContext(s) {
   _vertex_element_array = NULL;
   _vertex_declaration = NULL;
 
@@ -46,7 +46,6 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
   CGcontext context = DCAST(DXGraphicsStateGuardian9, gsg)->_cg_context;
 
   if (s->get_language() == Shader::SL_Cg) {
-
     // Ask the shader to compile itself for us and to give us the resulting Cg
     // program objects.
     if (!s->cg_compile_for(gsg->_shader_caps, context,
@@ -63,7 +62,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
     HRESULT hr;
     bool success = true;
     hr = cgD3D9LoadProgram(_cg_program, FALSE, assembly_flags);
-    if (FAILED (hr)) {
+    if (FAILED(hr)) {
       dxgsg9_cat.error()
         << "cgD3D9LoadProgram failed " << D3DERRORSTRING(hr);
 
@@ -80,46 +79,26 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
 /**
  * xyz
  */
-CLP(ShaderContext)::
-~CLP(ShaderContext)() {
+DXShaderContext9::
+~DXShaderContext9() {
   release_resources();
 
-  if ( _vertex_declaration != NULL ) {
+  if (_vertex_declaration != NULL) {
     _vertex_declaration->Release();
     _vertex_declaration = NULL;
   }
 
-  if ( _vertex_element_array != NULL ) {
+  if (_vertex_element_array != NULL) {
     delete _vertex_element_array;
     _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
  * Cg contexts).
  */
-void CLP(ShaderContext)::
+void DXShaderContext9::
 release_resources() {
 #ifdef HAVE_CG
   if (_cg_program) {
@@ -139,9 +118,8 @@ release_resources() {
  * This function is to be called to enable a new shader.  It also initializes
  * all of the shader's input parameters.
  */
-bool CLP(ShaderContext)::
+bool DXShaderContext9::
 bind(GSG *gsg) {
-
   bool bind_state = false;
 
 #ifdef HAVE_CG
@@ -149,7 +127,7 @@ bind(GSG *gsg) {
     // clear the last cached FVF to make sure the next SetFVF call goes
     // through
 
-    gsg -> _last_fvf = 0;
+    gsg->_last_fvf = 0;
 
     // Pass in k-parameters and transform-parameters
     issue_parameters(gsg, Shader::SSD_general);
@@ -159,7 +137,7 @@ bind(GSG *gsg) {
     // Bind the shaders.
     bind_state = true;
     hr = cgD3D9BindProgram(_cg_program);
-    if (FAILED (hr)) {
+    if (FAILED(hr)) {
       dxgsg9_cat.error() << "cgD3D9BindProgram failed " << D3DERRORSTRING(hr);
 
       CGerror error = cgGetError();
@@ -178,9 +156,8 @@ bind(GSG *gsg) {
 /**
  * This function disables a currently-bound shader.
  */
-void CLP(ShaderContext)::
+void DXShaderContext9::
 unbind(GSG *gsg) {
-
 #ifdef HAVE_CG
   if (_cg_program) {
     HRESULT hr;
@@ -211,48 +188,59 @@ InternalName *global_internal_name_0 = 0;
 InternalName *global_internal_name_1 = 0;
 #endif
 
-void CLP(ShaderContext)::
+void DXShaderContext9::
 issue_parameters(GSG *gsg, int altered) {
 #ifdef HAVE_CG
   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();
           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:
-          cgD3D9SetUniform(p, (PN_stdfloat*)_ptr_data->_ptr);
+          cgSetParameterValuefc(p, input_size, (float *)ptr_data->_ptr);
           break;
 
         default:
           dxgsg9_cat.error()
-            << _ptr._id._name << ":" << "unrecognized parameter type\n";
+            << spec._id._name << ": unrecognized parameter type\n";
           release_resources();
           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) {
           continue;
         }
-        const LMatrix4 *val = gsg->fetch_specified_value(_shader->_mat_spec[i], altered);
+        const LMatrix4 *val = gsg->fetch_specified_value(spec, altered);
         if (val) {
           HRESULT hr;
           PN_stdfloat v [4];
@@ -263,83 +251,79 @@ issue_parameters(GSG *gsg, int altered) {
           const float *data;
           data = temp_matrix.get_data();
 
-          #if DEBUG_SHADER
+#if DEBUG_SHADER
           // 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:
             // TRANSPOSE REQUIRED
             temp_matrix.transpose_in_place();
             data = temp_matrix.get_data();
 
-            hr = cgD3D9SetUniform (p, data);
+            hr = cgD3D9SetUniform(p, data);
             break;
 
           case Shader::SMP_transpose:
             // NO TRANSPOSE REQUIRED
-            hr = cgD3D9SetUniform (p, data);
+            hr = cgD3D9SetUniform(p, data);
             break;
 
           case Shader::SMP_row0:
-            hr = cgD3D9SetUniform (p, data + 0);
+            hr = cgD3D9SetUniform(p, data + 0);
             break;
           case Shader::SMP_row1:
-            hr = cgD3D9SetUniform (p, data + 4);
+            hr = cgD3D9SetUniform(p, data + 4);
             break;
           case Shader::SMP_row2:
-            hr = cgD3D9SetUniform (p, data + 8);
+            hr = cgD3D9SetUniform(p, data + 8);
             break;
           case Shader::SMP_row3x1:
           case Shader::SMP_row3x2:
           case Shader::SMP_row3x3:
           case Shader::SMP_row3:
-            hr = cgD3D9SetUniform (p, data + 12);
+            hr = cgD3D9SetUniform(p, data + 12);
             break;
 
           case Shader::SMP_col0:
             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;
           case Shader::SMP_col1:
             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;
           case Shader::SMP_col2:
             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;
           case Shader::SMP_col3:
             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;
 
           default:
             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;
           }
 
-          if (FAILED (hr)) {
-
+          if (FAILED(hr)) {
             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()
-              << "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) {
               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.
  */
-void CLP(ShaderContext)::
+void DXShaderContext9::
 disable_shader_vertex_arrays(GSG *gsg) {
   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;
 }
@@ -372,8 +355,8 @@ disable_shader_vertex_arrays(GSG *gsg) {
  * because it may unnecessarily disable arrays then immediately reenable them.
  * 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);
 #ifdef HAVE_CG
   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
     // bad....
-    if ( _vertex_element_array != NULL ) {
+    if (_vertex_element_array != NULL) {
       delete _vertex_element_array;
     }
     _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.
 
     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 =
-        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";
         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];
-        if ( p == NULL ) {
+        if (p == NULL) {
           dxgsg9_cat.info() <<
             "No parameter in map for parameter " << var_index <<
             " (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;
-        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
           // 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
@@ -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 ( param_array_reader != array_reader ) {
+        if (param_array_reader != array_reader) {
           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";
           continue;
         }
 
-        if ( strncmp( semantic, "POSITION", strlen( "POSITION" ) ) == 0 ) {
+        if (strncmp(semantic, "POSITION", strlen("POSITION")) == 0) {
           if (numeric_type == Geom::NT_float32) {
             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 {
             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) {
             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 {
             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 ||
               numeric_type == Geom::NT_packed_dabc ||
               numeric_type == Geom::NT_uint8) {
             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 {
             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) {
             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 {
             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) {
             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 {
             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) {
             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 {
             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.
-      CLP(VertexBufferContext)* dvbc;
+      DXVertexBufferContext9 *dvbc;
       if (!gsg->setup_array_data(dvbc, array_reader, force)) {
         dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
         continue;
       }
 
       // 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)) {
         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;
 
-    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()) {
         // Note that the currently generated vertex declaration works but
         // 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....
-      if ( _vertex_declaration != NULL ) {
+      if (_vertex_declaration != NULL) {
         _vertex_declaration->Release();
         _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);
       } else {
-        hr = device->SetVertexDeclaration( _vertex_declaration );
+        hr = device->SetVertexDeclaration(_vertex_declaration);
         if (FAILED(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.
  */
-void CLP(ShaderContext)::
-disable_shader_texture_bindings(GSG *gsg)
-{
+void DXShaderContext9::
+disable_shader_texture_bindings(GSG *gsg) {
 #ifdef HAVE_CG
   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];
       if (p == NULL) {
         continue;
@@ -640,12 +620,10 @@ disable_shader_texture_bindings(GSG *gsg)
 
       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()
-          << "SetTexture ("
-          << texunit
-          << ", NULL) failed "
+          << "SetTexture(" << texunit << ", NULL) failed "
           << D3DERRORSTRING(hr);
       }
     }
@@ -660,60 +638,44 @@ disable_shader_texture_bindings(GSG *gsg)
  * because it may unnecessarily disable textures then immediately reenable
  * 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
   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) {
         continue;
       }
-      Texture *tex = NULL;
+
       int view = gsg->get_current_tex_view_offset();
-      InternalName *id = _shader->_tex_spec[i]._name;
       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.
-        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;
       }
+
       TextureContext *tc = tex->prepare_now(view, gsg->_prepared_objects, gsg);
       if (tc == (TextureContext*)NULL) {
         continue;
       }
 
       int texunit = cgGetParameterResourceIndex(p);
-
       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
-void assemble_shader_test(char *file_path)
-{
+void assemble_shader_test(char *file_path) {
   int flags;
   D3DXMACRO *defines;
   LPD3DXINCLUDE include;
@@ -735,17 +696,15 @@ void assemble_shader_test(char *file_path)
   shader = 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;
 
-    error_message = (char *) (error_messages -> GetBufferPointer ( ));
-    if (error_message)
-    {
+    error_message = (char *)error_messages->GetBufferPointer();
+    if (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 "shaderContext.h"
 
-#define CLP(name) DX##name##9
-#define CLASSPREFIX_QUOTED "DX"
-
 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
  */
-class EXPCL_PANDADX CLP(ShaderContext) : public ShaderContext {
+class EXPCL_PANDADX DXShaderContext9 : public ShaderContext {
 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);
   bool bind(GSG *gsg);
@@ -55,10 +68,10 @@ public:
   void issue_parameters(GSG *gsg, int altered);
   void issue_transform(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);
   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;
   LPDIRECT3DVERTEXDECLARATION9 _vertex_declaration;
@@ -83,7 +96,7 @@ public:
   }
   static void init_type() {
     TypedObject::init_type();
-    register_type(_type_handle, CLASSPREFIX_QUOTED "ShaderContext",
+    register_type(_type_handle, "DXShaderContext9",
                   TypedObject::get_class_type());
   }
   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),
   _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
  * eviction will be requested again much later).
  */
-void CLP(VertexBufferContext)::
+void DXVertexBufferContext9::
 evict_lru() {
   dequeue_lru();
 

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

@@ -19,17 +19,17 @@
 #include "vertexBufferContext.h"
 #include "deletedChain.h"
 
-class CLP(GraphicsStateGuardian);
+class DXGraphicsStateGuardian9;
 
 /**
  * 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:
-  CLP(VertexBufferContext)(CLP(GraphicsStateGuardian) *dxgsg,
+  DXVertexBufferContext9(DXGraphicsStateGuardian9 *dxgsg,
                            PreparedGraphicsObjects *pgo,
                            GeomVertexArrayData *data);
-  ALLOC_DELETED_CHAIN(CLP(VertexBufferContext));
+  ALLOC_DELETED_CHAIN(DXVertexBufferContext9);
 
   virtual void evict_lru();
 

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

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

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

@@ -138,11 +138,7 @@ has_uvw(const string &name) const {
 bool EggVertex::
 has_aux(const string &name) const {
   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 "eventParameter.h"
 
-#ifdef HAVE_PYTHON
-#include "py_panda.h"
-#endif
-
 AtomicAdjust::Integer AsyncTask::_next_task_id;
 PStatCollector AsyncTask::_show_code_pcollector("App:Show code");
 TypeHandle AsyncTask::_type_handle;
@@ -48,9 +44,6 @@ AsyncTask(const string &name) :
   _total_dt(0.0),
   _num_frames(0)
 {
-#ifdef HAVE_PYTHON
-  _python_object = NULL;
-#endif  // HAVE_PYTHON
   set_name(name);
 
   // 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() {
   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 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_max_dt() const;
   INLINE double get_average_dt() const;
@@ -140,11 +135,6 @@ protected:
   static PStatCollector _show_code_pcollector;
   PStatCollector _task_pcollector;
 
-private:
-#ifdef HAVE_PYTHON
-  PyObject *_python_object;
-#endif  // HAVE_PYTHON
-
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

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

@@ -10,37 +10,3 @@
  * @author drose
  * @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
 #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
 extern struct Dtool_PyTypedObject Dtool_TypedReferenceCount;
@@ -188,6 +185,19 @@ get_upon_death() {
  */
 void PythonTask::
 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) {
     unregister_from_owner();
   }
@@ -391,8 +401,7 @@ do_python_task() {
   if (_generator == (PyObject *)NULL) {
     // We are calling the function directly.
     PyObject *args = get_args();
-    result =
-      Thread::get_current_thread()->call_python_func(_function, args);
+    result = PythonThread::call_python_func(_function, args);
     Py_DECREF(args);
 
 #ifdef PyGen_Check
@@ -494,10 +503,16 @@ do_python_task() {
   ostringstream strm;
 #if PY_MAJOR_VERSION >= 3
   PyObject *str = PyObject_ASCII(result);
+  if (str == NULL) {
+    str = PyUnicode_FromString("<repr error>");
+  }
   strm
     << *this << " returned " << PyUnicode_AsUTF8(str);
 #else
   PyObject *str = PyObject_Repr(result);
+  if (str == NULL) {
+    str = PyString_FromString("<repr error>");
+  }
   strm
     << *this << " returned " << PyString_AsString(str);
 #endif
@@ -606,18 +621,9 @@ call_owner_method(const char *method_name) {
   if (_owner != Py_None) {
     PyObject *func = PyObject_GetAttrString(_owner, (char *)method_name);
     if (func == (PyObject *)NULL) {
-#if PY_MAJOR_VERSION >= 3
-      PyObject *str = PyObject_ASCII(_owner);
       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 {
       call_function(func);

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

@@ -50,9 +50,6 @@ PUBLISHED:
   int __traverse__(visitproc visit, void *arg);
   int __clear__();
 
-  INLINE void set_delay(PyObject *delay);
-  INLINE PyObject *get_delay() const;
-
 PUBLISHED:
   // The name of this task.
   MAKE_PROPERTY(name, get_name, set_name);
@@ -72,10 +69,10 @@ PUBLISHED:
   MAKE_PROPERTY(wakeTime, get_wake_time);
 
   // 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.
-  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,
   // according to the task manager's clock.

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

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

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

@@ -129,7 +129,7 @@ node_ref() const {
 #endif
 
   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?
   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 bool node_unref() const;
   INLINE bool test_ref_count_integrity() const;
-
-protected:
   INLINE void node_unref_only() const;
 
+protected:
   bool do_test_ref_count_integrity() const;
 
 private:
-  AtomicAdjust::Integer _node_ref_count;
+  mutable AtomicAdjust::Integer _node_ref_count;
 
 public:
   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,
         TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR last,
         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) {
     // 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;
 
 #ifdef HAVE_PYTHON
-#if PY_VERSION_HEX >= 0x02060000
   EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags));
   EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
 #endif
-#endif
 
 #else  // CPPPARSER
   // This is the actual, complete interface.
@@ -257,11 +255,9 @@ PUBLISHED:
   INLINE int get_node_ref_count() const;
 
 #ifdef HAVE_PYTHON
-#if PY_VERSION_HEX >= 0x02060000
   EXTENSION(int __getbuffer__(PyObject *self, Py_buffer *view, int flags) const);
   EXTENSION(void __releasebuffer__(PyObject *self, Py_buffer *view) const);
 #endif
-#endif
 
 #else  // CPPPARSER
   // 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];
 }
 
-#if PY_VERSION_HEX >= 0x02060000
 /**
  * This is used to implement the buffer protocol, in order to allow efficient
  * access to the array data through a Python multiview object.
@@ -183,7 +182,7 @@ __getitem__(size_t n) const {
 template<class Element>
 INLINE int Extension<PointerToArray<Element> >::
 __getbuffer__(PyObject *self, Py_buffer *view, int flags) {
-
+#if PY_VERSION_HEX >= 0x02060000
   const char *format = get_format_code(Element);
   if (format == NULL) {
     // Not supported.
@@ -222,6 +221,9 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) {
   view->internal = (void*) this->_this;
 
   return 0;
+#else
+  return -1;
+#endif
 }
 
 /**
@@ -230,13 +232,14 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) {
 template<class Element>
 INLINE void Extension<PointerToArray<Element> >::
 __releasebuffer__(PyObject *self, Py_buffer *view) const {
+#if PY_VERSION_HEX >= 0x02060000
   // Note: PyBuffer_Release automatically decrements view->obj.
-
   if (view->internal != NULL) {
     // Oh, right, let's not forget to unref this.
     unref_delete((const PointerToArray<Element> *)view->internal);
     view->internal = NULL;
   }
+#endif
 }
 
 /**
@@ -246,7 +249,7 @@ __releasebuffer__(PyObject *self, Py_buffer *view) const {
 template<class Element>
 INLINE int Extension<ConstPointerToArray<Element> >::
 __getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
-
+#if PY_VERSION_HEX >= 0x02060000
   if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
     PyErr_SetString(PyExc_BufferError,
                     "Object is not writable.");
@@ -291,6 +294,9 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
   view->internal = (void*) this->_this;
 
   return 0;
+#else
+  return -1;
+#endif
 }
 
 /**
@@ -299,12 +305,12 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) const {
 template<class Element>
 INLINE void Extension<ConstPointerToArray<Element> >::
 __releasebuffer__(PyObject *self, Py_buffer *view) const {
+#if PY_VERSION_HEX >= 0x02060000
   // Note: PyBuffer_Release automatically decrements obj->view.
-
   if (view->internal != NULL) {
     // Oh, right, let's not forget to unref this.
     unref_delete((const PointerToArray<Element> *)view->internal);
     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 void __setitem__(size_t n, const Element &value);
 
-#if PY_VERSION_HEX >= 0x02060000
   INLINE int __getbuffer__(PyObject *self, Py_buffer *view, int flags);
   INLINE void __releasebuffer__(PyObject *self, Py_buffer *view) const;
-#endif
 };
 
 /**
@@ -55,10 +53,8 @@ public:
 
   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 void __releasebuffer__(PyObject *self, Py_buffer *view) const;
-#endif
 };
 
 #ifdef _MSC_VER

Some files were not shown because too many files changed in this diff