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

This commit is contained in:
David Rose 2006-10-11 18:17:38 +00:00
parent 378c3757d5
commit c6681570d0
6 changed files with 139 additions and 29 deletions

View File

@ -28,7 +28,17 @@ DXGeomMunger8(GraphicsStateGuardian *gsg, const RenderState *state) :
_texture(state->get_texture()),
_tex_gen(state->get_tex_gen())
{
_filtered_texture = (TextureAttrib *)NULL;
_reffed_filtered_texture = false;
if (_texture != (TextureAttrib *)NULL) {
_texture = _texture->filter_to_max(gsg->get_max_texture_stages());
_filtered_texture = _texture->filter_to_max(gsg->get_max_texture_stages());
if (_filtered_texture != _texture) {
_filtered_texture->ref();
_reffed_filtered_texture = true;
}
}
// 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

@ -24,6 +24,37 @@
GeomMunger *DXGeomMunger8::_deleted_chain = NULL;
TypeHandle DXGeomMunger8::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: DXGeomMunger8::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
DXGeomMunger8::
~DXGeomMunger8() {
if (_reffed_filtered_texture) {
unref_delete(_filtered_texture);
_reffed_filtered_texture = false;
}
}
////////////////////////////////////////////////////////////////////
// Function: DXGeomMunger8::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 DXGeomMunger8::
wp_callback(void *) {
unregister_myself();
if (_reffed_filtered_texture) {
unref_delete(_filtered_texture);
_reffed_filtered_texture = false;
}
}
////////////////////////////////////////////////////////////////////
// Function: DXGeomMunger8::munge_format_impl
// Access: Protected, Virtual
@ -110,13 +141,13 @@ munge_format_impl(const GeomVertexFormat *orig,
// Now copy all of the texture coordinates in, in order by stage
// index. But we have to reuse previous columns.
if (_texture != (TextureAttrib *)NULL) {
if (_filtered_texture != (TextureAttrib *)NULL) {
typedef pset<const InternalName *> UsedStages;
UsedStages used_stages;
int num_stages = _texture->get_num_on_stages();
int num_stages = _filtered_texture->get_num_on_stages();
for (int i = 0; i < num_stages; ++i) {
TextureStage *stage = _texture->get_on_stage(i);
TextureStage *stage = _filtered_texture->get_on_stage(i);
InternalName *name = stage->get_texcoord_name();
if (used_stages.insert(name).second) {
@ -154,8 +185,8 @@ munge_format_impl(const GeomVertexFormat *orig,
int DXGeomMunger8::
compare_to_impl(const GeomMunger *other) const {
const DXGeomMunger8 *om = DCAST(DXGeomMunger8, other);
if (_texture != om->_texture) {
return _texture < om->_texture ? -1 : 1;
if (_filtered_texture != om->_filtered_texture) {
return _filtered_texture < om->_filtered_texture ? -1 : 1;
}
if (_tex_gen != om->_tex_gen) {
return _tex_gen < om->_tex_gen ? -1 : 1;
@ -174,12 +205,13 @@ compare_to_impl(const GeomMunger *other) const {
////////////////////////////////////////////////////////////////////
int DXGeomMunger8::
geom_compare_to_impl(const GeomMunger *other) const {
// Unlike GLGeomMunger, we do consider _texture and _tex_gen
// important for this purpose, since they control the number and
// order of texture coordinates we might put into the FVF.
// Unlike GLGeomMunger, we do consider _filtered_texture and
// _tex_gen important for this purpose, since they control the
// number and order of texture coordinates we might put into the
// FVF.
const DXGeomMunger8 *om = DCAST(DXGeomMunger8, other);
if (_texture != om->_texture) {
return _texture < om->_texture ? -1 : 1;
if (_filtered_texture != om->_filtered_texture) {
return _filtered_texture < om->_filtered_texture ? -1 : 1;
}
if (_tex_gen != om->_tex_gen) {
return _tex_gen < om->_tex_gen ? -1 : 1;

View File

@ -22,6 +22,8 @@
#include "pandabase.h"
#include "standardMunger.h"
#include "graphicsStateGuardian.h"
#include "weakPointerTo.h"
#include "weakPointerCallback.h"
////////////////////////////////////////////////////////////////////
// Class : DXGeomMunger8
@ -31,11 +33,14 @@
// and that all relevant components are packed into a
// single array, in the correct order.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDADX DXGeomMunger8 : public StandardMunger {
class EXPCL_PANDADX DXGeomMunger8 : public StandardMunger, public WeakPointerCallback {
public:
INLINE DXGeomMunger8(GraphicsStateGuardian *gsg, const RenderState *state);
virtual ~DXGeomMunger8();
ALLOC_DELETED_CHAIN(DXGeomMunger8);
virtual void wp_callback(void *);
protected:
virtual CPT(GeomVertexFormat) munge_format_impl(const GeomVertexFormat *orig,
const GeomVertexAnimationSpec &animation);
@ -44,8 +49,16 @@ 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;
// This pointer is derived from _texture, above. In the case that
// it is a different pointer, we maintain its reference count
// explicitly. If it is the same pointer, we don't reference count
// it at all (so we won't hold on to the reference count
// unnecessarily).
const TextureAttrib *_filtered_texture;
bool _reffed_filtered_texture;
static GeomMunger *_deleted_chain;

View File

@ -28,8 +28,18 @@ DXGeomMunger9(GraphicsStateGuardian *gsg, const RenderState *state) :
_texture(state->get_texture()),
_tex_gen(state->get_tex_gen())
{
_filtered_texture = (TextureAttrib *)NULL;
_reffed_filtered_texture = false;
if (_texture != (TextureAttrib *)NULL) {
_texture = _texture->filter_to_max(gsg->get_max_texture_stages());
_filtered_texture = _texture->filter_to_max(gsg->get_max_texture_stages());
if (_filtered_texture != _texture) {
_filtered_texture->ref();
_reffed_filtered_texture = true;
}
}
// 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

@ -24,6 +24,37 @@
GeomMunger *DXGeomMunger9::_deleted_chain = NULL;
TypeHandle DXGeomMunger9::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: DXGeomMunger9::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
DXGeomMunger9::
~DXGeomMunger9() {
if (_reffed_filtered_texture) {
unref_delete(_filtered_texture);
_reffed_filtered_texture = false;
}
}
////////////////////////////////////////////////////////////////////
// Function: DXGeomMunger9::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 DXGeomMunger9::
wp_callback(void *) {
unregister_myself();
if (_reffed_filtered_texture) {
unref_delete(_filtered_texture);
_reffed_filtered_texture = false;
}
}
////////////////////////////////////////////////////////////////////
// Function: DXGeomMunger9::munge_format_impl
// Access: Protected, Virtual
@ -37,7 +68,7 @@ munge_format_impl(const GeomVertexFormat *orig,
if (animation.get_animation_type() != AT_none) {
dxgsg9_cat.debug()
<< "preparing animation type " << animation << " for " << *orig
<< "\n";
<< "\n";
}
}
// We have to build a completely new format that includes only the
@ -110,13 +141,13 @@ munge_format_impl(const GeomVertexFormat *orig,
// Now copy all of the texture coordinates in, in order by stage
// index. But we have to reuse previous columns.
if (_texture != (TextureAttrib *)NULL) {
if (_filtered_texture != (TextureAttrib *)NULL) {
typedef pset<const InternalName *> UsedStages;
UsedStages used_stages;
int num_stages = _texture->get_num_on_stages();
int num_stages = _filtered_texture->get_num_on_stages();
for (int i = 0; i < num_stages; ++i) {
TextureStage *stage = _texture->get_on_stage(i);
TextureStage *stage = _filtered_texture->get_on_stage(i);
InternalName *name = stage->get_texcoord_name();
if (used_stages.insert(name).second) {
@ -154,8 +185,8 @@ munge_format_impl(const GeomVertexFormat *orig,
int DXGeomMunger9::
compare_to_impl(const GeomMunger *other) const {
const DXGeomMunger9 *om = DCAST(DXGeomMunger9, other);
if (_texture != om->_texture) {
return _texture < om->_texture ? -1 : 1;
if (_filtered_texture != om->_filtered_texture) {
return _filtered_texture < om->_filtered_texture ? -1 : 1;
}
if (_tex_gen != om->_tex_gen) {
return _tex_gen < om->_tex_gen ? -1 : 1;
@ -174,12 +205,13 @@ compare_to_impl(const GeomMunger *other) const {
////////////////////////////////////////////////////////////////////
int DXGeomMunger9::
geom_compare_to_impl(const GeomMunger *other) const {
// Unlike GLGeomMunger, we do consider _texture and _tex_gen
// important for this purpose, since they control the number and
// order of texture coordinates we might put into the FVF.
// Unlike GLGeomMunger, we do consider _filtered_texture and
// _tex_gen important for this purpose, since they control the
// number and order of texture coordinates we might put into the
// FVF.
const DXGeomMunger9 *om = DCAST(DXGeomMunger9, other);
if (_texture != om->_texture) {
return _texture < om->_texture ? -1 : 1;
if (_filtered_texture != om->_filtered_texture) {
return _filtered_texture < om->_filtered_texture ? -1 : 1;
}
if (_tex_gen != om->_tex_gen) {
return _tex_gen < om->_tex_gen ? -1 : 1;

View File

@ -22,6 +22,8 @@
#include "pandabase.h"
#include "standardMunger.h"
#include "graphicsStateGuardian.h"
#include "weakPointerTo.h"
#include "weakPointerCallback.h"
////////////////////////////////////////////////////////////////////
// Class : DXGeomMunger9
@ -31,11 +33,14 @@
// and that all relevant components are packed into a
// single array, in the correct order.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDADX DXGeomMunger9 : public StandardMunger {
class EXPCL_PANDADX DXGeomMunger9 : public StandardMunger, public WeakPointerCallback {
public:
INLINE DXGeomMunger9(GraphicsStateGuardian *gsg, const RenderState *state);
virtual ~DXGeomMunger9();
ALLOC_DELETED_CHAIN(DXGeomMunger9);
virtual void wp_callback(void *);
protected:
virtual CPT(GeomVertexFormat) munge_format_impl(const GeomVertexFormat *orig,
const GeomVertexAnimationSpec &animation);
@ -44,8 +49,16 @@ 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;
// This pointer is derived from _texture, above. In the case that
// it is a different pointer, we maintain its reference count
// explicitly. If it is the same pointer, we don't reference count
// it at all (so we won't hold on to the reference count
// unnecessarily).
const TextureAttrib *_filtered_texture;
bool _reffed_filtered_texture;
static GeomMunger *_deleted_chain;