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

This commit is contained in:
David Rose 2006-10-07 00:34:26 +00:00
parent 7ec8c920a7
commit 2b00d098f2
13 changed files with 193 additions and 35 deletions

View File

@ -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 \

View File

@ -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"

View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////

View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "weakPointerCallback.h"

View File

@ -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
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#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

View File

@ -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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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"

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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.
// It is not an error to call this if the munger has
// already been unregistered.
////////////////////////////////////////////////////////////////////
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);
INLINE void GeomMunger::
unregister_myself() {
if (is_registered()) {
get_registry()->unregister_munger(this);
}
////////////////////////////////////////////////////////////////////
// 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);
}
////////////////////////////////////////////////////////////////////

View File

@ -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());
}

View File

@ -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);