mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
don't let geom-vertex-cache hang on to textures
This commit is contained in:
parent
378c3757d5
commit
c6681570d0
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user