ソースを参照

don't let geom-vertex-cache hang on to textures

David Rose 19 年 前
コミット
2b00d098f2

+ 3 - 0
panda/src/express/Sources.pp

@@ -62,6 +62,7 @@
     virtualFileMountMultifile.I virtualFileMountSystem.h \
     virtualFileMountSystem.I virtualFileSimple.h virtualFileSimple.I \
     virtualFileSystem.h virtualFileSystem.I \
+    weakPointerCallback.I weakPointerCallback.h \
     weakPointerTo.I weakPointerTo.h \
     weakPointerToBase.I weakPointerToBase.h \
     weakPointerToVoid.I weakPointerToVoid.h \
@@ -112,6 +113,7 @@
     virtualFileMount.cxx \
     virtualFileMountMultifile.cxx virtualFileMountSystem.cxx \
     virtualFileSimple.cxx virtualFileSystem.cxx \
+    weakPointerCallback.cxx \
     weakPointerTo.cxx \
     weakPointerToBase.cxx \
     weakPointerToVoid.cxx \
@@ -173,6 +175,7 @@
     virtualFileMountMultifile.I virtualFileMountSystem.h \
     virtualFileMountSystem.I virtualFileSimple.h virtualFileSimple.I \
     virtualFileSystem.h virtualFileSystem.I \
+    weakPointerCallback.I weakPointerCallback.h \
     weakPointerTo.I weakPointerTo.h \
     weakPointerToBase.I weakPointerToBase.h \
     weakPointerToVoid.I weakPointerToVoid.h \

+ 1 - 0
panda/src/express/express_composite2.cxx

@@ -22,6 +22,7 @@
 #include "virtualFileMountSystem.cxx"
 #include "virtualFileSimple.cxx"
 #include "virtualFileSystem.cxx"
+#include "weakPointerCallback.cxx"
 #include "weakPointerTo.cxx"
 #include "weakPointerToBase.cxx"
 #include "weakPointerToVoid.cxx"

+ 18 - 0
panda/src/express/weakPointerCallback.I

@@ -0,0 +1,18 @@
+// Filename: weakPointerCallback.I
+// Created by:  drose (06Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+

+ 19 - 0
panda/src/express/weakPointerCallback.cxx

@@ -0,0 +1,19 @@
+// Filename: weakPointerCallback.cxx
+// Created by:  drose (06Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "weakPointerCallback.h"

+ 38 - 0
panda/src/express/weakPointerCallback.h

@@ -0,0 +1,38 @@
+// Filename: weakPointerCallback.h
+// Created by:  drose (06Oct06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef WEAKPOINTERCALLBACK_H
+#define WEAKPOINTERCALLBACK_H
+
+#include "pandabase.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : WeakPointerCallback
+// Description : Derive from this class and override the callback()
+//               method if you want to get an immediate callback from
+//               a WeakPointerTo object when its referenced pointer is
+//               deleted.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDAEXPRESS WeakPointerCallback {
+public:
+  virtual void wp_callback(void *pointer)=0;
+};
+
+#include "weakPointerCallback.I"
+
+#endif

+ 34 - 0
panda/src/express/weakPointerToVoid.I

@@ -25,6 +25,7 @@
 INLINE WeakPointerToVoid::
 WeakPointerToVoid() {
   _ptr_was_deleted = false;
+  _callback = NULL;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -48,6 +49,39 @@ INLINE void WeakPointerToVoid::
 mark_deleted() {
   nassertv(!_ptr_was_deleted);
   _ptr_was_deleted = true;
+  if (_callback != (WeakPointerCallback *)NULL) {
+    _callback->wp_callback(_void_ptr);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: WeakPointerToVoid::set_callback
+//       Access: Public
+//  Description: Sets a callback that will be made when the pointer is
+//               deleted.  If a previous callback has already been
+//               set, it will be replaced.
+//
+//               If the pointer has already been deleted, the callback
+//               will be made immediately.
+////////////////////////////////////////////////////////////////////
+INLINE void WeakPointerToVoid::
+set_callback(WeakPointerCallback *callback) {
+  _callback = callback;
+  if (_ptr_was_deleted && _callback != (WeakPointerCallback *)NULL) {
+    _callback->wp_callback(_void_ptr);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: WeakPointerToVoid::get_callback
+//       Access: Public
+//  Description: Returns the callback that will be made when the
+//               pointer is deleted, or NULL if no callback has been
+//               set.
+////////////////////////////////////////////////////////////////////
+INLINE WeakPointerCallback *WeakPointerToVoid::
+get_callback() const {
+  return _callback;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 5 - 0
panda/src/express/weakPointerToVoid.h

@@ -21,6 +21,7 @@
 
 #include "pandabase.h"
 #include "pointerToVoid.h"
+#include "weakPointerCallback.h"
 
 ////////////////////////////////////////////////////////////////////
 //       Class : WeakPointerToVoid
@@ -36,12 +37,16 @@ protected:
 public:
   INLINE void mark_deleted();
 
+  INLINE void set_callback(WeakPointerCallback *callback);
+  INLINE WeakPointerCallback *get_callback() const;
+
 PUBLISHED:
   INLINE bool was_deleted() const;
   INLINE bool is_valid_pointer() const;
 
 protected:
   bool _ptr_was_deleted;
+  WeakPointerCallback *_callback;
 };
 
 #include "weakPointerToVoid.I"

+ 4 - 0
panda/src/glstuff/glGeomMunger_src.I

@@ -28,4 +28,8 @@ CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state) :
   _texture(state->get_texture()),
   _tex_gen(state->get_tex_gen())
 {
+  // Set a callback to unregister ourselves when either the Texture or
+  // the TexGen object gets deleted.
+  _texture.set_callback(this);
+  _tex_gen.set_callback(this);
 }

+ 13 - 0
panda/src/glstuff/glGeomMunger_src.cxx

@@ -37,6 +37,19 @@ CLP(GeomMunger)::
   _geom_contexts.clear();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CLP(GeomMunger)::wp_callback
+//       Access: Public, Virtual
+//  Description: This callback is set to be made whenever the
+//               associated _texture or _tex_gen attributes are
+//               destructed, in which case the GeomMunger is invalid
+//               and should no longer be used.
+////////////////////////////////////////////////////////////////////
+void CLP(GeomMunger)::
+wp_callback(void *) {
+  unregister_myself();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CLP(GeomMunger)::munge_format_impl
 //       Access: Protected, Virtual

+ 7 - 3
panda/src/glstuff/glGeomMunger_src.h

@@ -22,6 +22,8 @@
 #include "textureAttrib.h"
 #include "texGenAttrib.h"
 #include "renderState.h"
+#include "weakPointerTo.h"
+#include "weakPointerCallback.h"
 
 class CLP(GeomContext);
 
@@ -31,12 +33,14 @@ class CLP(GeomContext);
 //               for OpenGL rendering.  In particular, it makes sure
 //               colors aren't stored in DirectX's packed_argb format.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_GL CLP(GeomMunger) : public StandardMunger {
+class EXPCL_GL CLP(GeomMunger) : public StandardMunger, public WeakPointerCallback {
 public:
   INLINE CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state);
   virtual ~CLP(GeomMunger)();
   ALLOC_DELETED_CHAIN(CLP(GeomMunger));
 
+  virtual void wp_callback(void *);
+
 protected:
   virtual CPT(GeomVertexFormat) munge_format_impl(const GeomVertexFormat *orig,
                                                     const GeomVertexAnimationSpec &animation);
@@ -44,8 +48,8 @@ protected:
   virtual int geom_compare_to_impl(const GeomMunger *other) const;
 
 private:
-  CPT(TextureAttrib) _texture;
-  CPT(TexGenAttrib) _tex_gen;
+  WCPT(TextureAttrib) _texture;
+  WCPT(TexGenAttrib) _tex_gen;
 
   typedef pset<CLP(GeomContext) *> GeomContexts;
   GeomContexts _geom_contexts;

+ 48 - 29
panda/src/gobj/geomMunger.I

@@ -50,6 +50,40 @@ register_munger(GeomMunger *munger, Thread *current_thread) {
   return get_registry()->register_munger(munger, current_thread);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomMunger::munge_format
+//       Access: Public
+//  Description: Given a source GeomVertexFormat, converts it if
+//               necessary to the appropriate format for rendering.
+//
+//               If the GeomVertexAnimationSpec so indicates, then the
+//               format will be chosen to convert CPU-based animation
+//               tables to HW-based animation tables, reserving space
+//               for the specified number of transforms per vertex.
+////////////////////////////////////////////////////////////////////
+INLINE CPT(GeomVertexFormat) GeomMunger::
+munge_format(const GeomVertexFormat *format,
+             const GeomVertexAnimationSpec &animation) const {
+  // We cast away the const pointer, because do_munge_format() needs
+  // to update caches and stuff, but we trust it not to change any
+  // user-definable parameters.
+  return ((GeomMunger *)this)->do_munge_format(format, animation);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GeomMunger::munge_data
+//       Access: Public
+//  Description: Given a source GeomVertexData, converts it if
+//               necessary to the appropriate data for rendering.
+////////////////////////////////////////////////////////////////////
+INLINE CPT(GeomVertexData) GeomMunger::
+munge_data(const GeomVertexData *data) const {
+  // We cast away the const pointer, because do_munge_data() needs to
+  // update caches and stuff, but we trust it not to change any
+  // user-definable parameters.
+  return ((GeomMunger *)this)->munge_data_impl(data);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomMunger::compare_to
 //       Access: Public
@@ -96,37 +130,22 @@ geom_compare_to(const GeomMunger &other) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GeomMunger::munge_format
-//       Access: Public
-//  Description: Given a source GeomVertexFormat, converts it if
-//               necessary to the appropriate format for rendering.
+//     Function: GeomMunger::unregister_myself
+//       Access: Protected
+//  Description: Unregisters the GeomMunger, for instance when it is
+//               being destructed, or whenever it has become invalid
+//               for some reason.  This removes it from the registry
+//               so that it will no longer be available to be returned
+//               by register_munger().
 //
-//               If the GeomVertexAnimationSpec so indicates, then the
-//               format will be chosen to convert CPU-based animation
-//               tables to HW-based animation tables, reserving space
-//               for the specified number of transforms per vertex.
-////////////////////////////////////////////////////////////////////
-INLINE CPT(GeomVertexFormat) GeomMunger::
-munge_format(const GeomVertexFormat *format,
-             const GeomVertexAnimationSpec &animation) const {
-  // We cast away the const pointer, because do_munge_format() needs
-  // to update caches and stuff, but we trust it not to change any
-  // user-definable parameters.
-  return ((GeomMunger *)this)->do_munge_format(format, animation);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GeomMunger::munge_data
-//       Access: Public
-//  Description: Given a source GeomVertexData, converts it if
-//               necessary to the appropriate data for rendering.
+//               It is not an error to call this if the munger has
+//               already been unregistered.
 ////////////////////////////////////////////////////////////////////
-INLINE CPT(GeomVertexData) GeomMunger::
-munge_data(const GeomVertexData *data) const {
-  // We cast away the const pointer, because do_munge_data() needs to
-  // update caches and stuff, but we trust it not to change any
-  // user-definable parameters.
-  return ((GeomMunger *)this)->munge_data_impl(data);
+INLINE void GeomMunger::
+unregister_myself() {
+  if (is_registered()) {
+    get_registry()->unregister_munger(this);
+  }
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 3
panda/src/gobj/geomMunger.cxx

@@ -76,9 +76,7 @@ operator = (const GeomMunger &copy) {
 ////////////////////////////////////////////////////////////////////
 GeomMunger::
 ~GeomMunger() {
-  if (is_registered()) {
-    get_registry()->unregister_munger(this);
-  }
+  unregister_myself();
   nassertv(_formats_by_animation.empty());
 }
 

+ 2 - 0
panda/src/gobj/geomMunger.h

@@ -81,6 +81,8 @@ public:
   INLINE int geom_compare_to(const GeomMunger &other) const;
 
 protected:
+  INLINE void unregister_myself();
+
   CPT(GeomVertexFormat) do_munge_format(const GeomVertexFormat *format,
                                           const GeomVertexAnimationSpec &animation);