mirror of
https://github.com/Relintai/terraman.git
synced 2025-04-21 21:41:20 +02:00
Implement refcounting for material caches.
This commit is contained in:
parent
8f989f7ae0
commit
94c9fc39ac
@ -29,6 +29,19 @@ void TerraMaterialCache::set_initialized(const bool value) {
|
||||
_initialized = value;
|
||||
}
|
||||
|
||||
int TerraMaterialCache::get_ref_count() {
|
||||
return _ref_count;
|
||||
}
|
||||
void TerraMaterialCache::set_ref_count(const int value) {
|
||||
_ref_count = value;
|
||||
}
|
||||
void TerraMaterialCache::inc_ref_count() {
|
||||
_ref_count += 1;
|
||||
}
|
||||
void TerraMaterialCache::dec_ref_count() {
|
||||
_ref_count -= 1;
|
||||
}
|
||||
|
||||
//Materials
|
||||
Ref<Material> TerraMaterialCache::material_get(const int index) {
|
||||
ERR_FAIL_INDEX_V(index, _materials.size(), Ref<Material>(NULL));
|
||||
@ -143,7 +156,7 @@ void TerraMaterialCache::setup_material_albedo(Ref<Texture> texture) {
|
||||
}
|
||||
|
||||
TerraMaterialCache::TerraMaterialCache() {
|
||||
material_users = 0;
|
||||
_ref_count = 0;
|
||||
_initialized = false;
|
||||
}
|
||||
|
||||
@ -157,6 +170,12 @@ void TerraMaterialCache::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_initialized", "value"), &TerraMaterialCache::set_initialized);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "initialized"), "set_initialized", "get_initialized");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_ref_count"), &TerraMaterialCache::get_ref_count);
|
||||
ClassDB::bind_method(D_METHOD("set_ref_count", "value"), &TerraMaterialCache::set_ref_count);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "mat_ref_count"), "set_ref_count", "get_ref_count");
|
||||
ClassDB::bind_method(D_METHOD("inc_ref_count"), &TerraMaterialCache::inc_ref_count);
|
||||
ClassDB::bind_method(D_METHOD("dec_ref_count"), &TerraMaterialCache::dec_ref_count);
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_setup_material_albedo", PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture")));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("material_get", "index"), &TerraMaterialCache::material_get);
|
||||
|
@ -51,6 +51,11 @@ public:
|
||||
bool get_initialized();
|
||||
void set_initialized(const bool value);
|
||||
|
||||
int get_ref_count();
|
||||
void set_ref_count(const int value);
|
||||
void inc_ref_count();
|
||||
void dec_ref_count();
|
||||
|
||||
Ref<Material> material_get(const int index);
|
||||
Ref<Material> material_lod_get(const int index);
|
||||
void material_add(const Ref<Material> &value);
|
||||
@ -84,8 +89,8 @@ protected:
|
||||
|
||||
Vector<Ref<TerraSurface>> _surfaces;
|
||||
Vector<Ref<Material>> _materials;
|
||||
|
||||
int material_users;
|
||||
|
||||
int _ref_count;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -84,6 +84,12 @@ Ref<TerraMaterialCache> TerramanLibrary::_material_cache_get(const int key) {
|
||||
ERR_FAIL_V_MSG(Ref<TerraMaterialCache>(), "This TerramanLibrary doesn't support cached materials!");
|
||||
}
|
||||
|
||||
void TerramanLibrary::material_cache_unref(const int key) {
|
||||
call("_material_cache_unref", key);
|
||||
}
|
||||
void TerramanLibrary::_material_cache_unref(const int key) {
|
||||
}
|
||||
|
||||
void TerramanLibrary::material_add(const Ref<Material> &value) {
|
||||
ERR_FAIL_COND(!value.is_valid());
|
||||
|
||||
@ -158,6 +164,12 @@ Ref<TerraMaterialCache> TerramanLibrary::_liquid_material_cache_get(const int ke
|
||||
ERR_FAIL_V_MSG(Ref<TerraMaterialCache>(), "This TerramanLibrary doesn't support cached liquid materials!");
|
||||
}
|
||||
|
||||
void TerramanLibrary::liquid_material_cache_unref(const int key) {
|
||||
call("_liquid_material_cache_unref", key);
|
||||
}
|
||||
void TerramanLibrary::_liquid_material_cache_unref(const int key) {
|
||||
}
|
||||
|
||||
void TerramanLibrary::liquid_material_add(const Ref<Material> &value) {
|
||||
ERR_FAIL_COND(!value.is_valid());
|
||||
|
||||
@ -232,6 +244,12 @@ Ref<TerraMaterialCache> TerramanLibrary::_prop_material_cache_get(const int key)
|
||||
ERR_FAIL_V_MSG(Ref<TerraMaterialCache>(), "This TerramanLibrary doesn't support cached prop materials!");
|
||||
}
|
||||
|
||||
void TerramanLibrary::prop_material_cache_unref(const int key) {
|
||||
call("_prop_material_cache_unref", key);
|
||||
}
|
||||
void TerramanLibrary::_prop_material_cache_unref(const int key) {
|
||||
}
|
||||
|
||||
void TerramanLibrary::prop_material_add(const Ref<Material> &value) {
|
||||
ERR_FAIL_COND(!value.is_valid());
|
||||
|
||||
@ -351,7 +369,8 @@ void TerramanLibrary::_bind_methods() {
|
||||
BIND_VMETHOD(MethodInfo("_setup_material_albedo", PropertyInfo(Variant::INT, "material_index"), PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture")));
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_material_cache_get_key", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "TerraChunk")));
|
||||
BIND_VMETHOD(MethodInfo("_material_cache_get", PropertyInfo(Variant::OBJECT, "key", PROPERTY_HINT_RESOURCE_TYPE, "TerraMaterialCache")));
|
||||
BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::OBJECT, "ret", PROPERTY_HINT_RESOURCE_TYPE, "TerraMaterialCache"), "_material_cache_get", PropertyInfo(Variant::INT, "key")));
|
||||
BIND_VMETHOD(MethodInfo("_material_cache_unref", PropertyInfo(Variant::INT, "key")));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("material_get", "index"), &TerramanLibrary::material_get);
|
||||
ClassDB::bind_method(D_METHOD("material_lod_get", "index"), &TerramanLibrary::material_lod_get);
|
||||
@ -360,6 +379,8 @@ void TerramanLibrary::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_material_cache_get_key", "chunk"), &TerramanLibrary::_material_cache_get_key);
|
||||
ClassDB::bind_method(D_METHOD("material_cache_get", "key"), &TerramanLibrary::material_cache_get);
|
||||
ClassDB::bind_method(D_METHOD("_material_cache_get", "key"), &TerramanLibrary::_material_cache_get);
|
||||
ClassDB::bind_method(D_METHOD("material_cache_unref", "key"), &TerramanLibrary::material_cache_unref);
|
||||
ClassDB::bind_method(D_METHOD("_material_cache_unref", "key"), &TerramanLibrary::_material_cache_unref);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("material_add", "value"), &TerramanLibrary::material_add);
|
||||
ClassDB::bind_method(D_METHOD("material_set", "index", "value"), &TerramanLibrary::material_set);
|
||||
@ -372,7 +393,8 @@ void TerramanLibrary::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "materials", PROPERTY_HINT_NONE, "17/17:Material", PROPERTY_USAGE_DEFAULT, "Material"), "materials_set", "materials_get");
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_liquid_material_cache_get_key", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "TerraChunk")));
|
||||
BIND_VMETHOD(MethodInfo("_liquid_material_cache_get", PropertyInfo(Variant::OBJECT, "key", PROPERTY_HINT_RESOURCE_TYPE, "TerraMaterialCache")));
|
||||
BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::OBJECT, "ret", PROPERTY_HINT_RESOURCE_TYPE, "TerraMaterialCache"), "_liquid_material_cache_get", PropertyInfo(Variant::INT, "key")));
|
||||
BIND_VMETHOD(MethodInfo("_liquid_material_cache_unref", PropertyInfo(Variant::INT, "key")));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("liquid_material_get", "index"), &TerramanLibrary::liquid_material_get);
|
||||
ClassDB::bind_method(D_METHOD("liquid_material_lod_get", "index"), &TerramanLibrary::liquid_material_lod_get);
|
||||
@ -381,6 +403,8 @@ void TerramanLibrary::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_liquid_material_cache_get_key", "chunk"), &TerramanLibrary::_liquid_material_cache_get_key);
|
||||
ClassDB::bind_method(D_METHOD("liquid_material_cache_get", "key"), &TerramanLibrary::liquid_material_cache_get);
|
||||
ClassDB::bind_method(D_METHOD("_liquid_material_cache_get", "key"), &TerramanLibrary::_liquid_material_cache_get);
|
||||
ClassDB::bind_method(D_METHOD("liquid_material_cache_unref", "key"), &TerramanLibrary::liquid_material_cache_unref);
|
||||
ClassDB::bind_method(D_METHOD("_liquid_material_cache_unref", "key"), &TerramanLibrary::_liquid_material_cache_unref);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("liquid_material_add", "value"), &TerramanLibrary::liquid_material_add);
|
||||
ClassDB::bind_method(D_METHOD("liquid_material_set", "index", "value"), &TerramanLibrary::liquid_material_set);
|
||||
@ -393,7 +417,8 @@ void TerramanLibrary::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "liquid_materials", PROPERTY_HINT_NONE, "17/17:Material", PROPERTY_USAGE_DEFAULT, "Material"), "liquid_materials_set", "liquid_materials_get");
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_prop_material_cache_get_key", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "TerraChunk")));
|
||||
BIND_VMETHOD(MethodInfo("_prop_material_cache_get", PropertyInfo(Variant::OBJECT, "key", PROPERTY_HINT_RESOURCE_TYPE, "TerraMaterialCache")));
|
||||
BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::OBJECT, "ret", PROPERTY_HINT_RESOURCE_TYPE, "TerraMaterialCache"), "_prop_material_cache_get", PropertyInfo(Variant::INT, "key")));
|
||||
BIND_VMETHOD(MethodInfo("_prop_material_cache_unref", PropertyInfo(Variant::INT, "key")));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("prop_material_get", "index"), &TerramanLibrary::prop_material_get);
|
||||
ClassDB::bind_method(D_METHOD("prop_material_lod_get", "index"), &TerramanLibrary::prop_material_lod_get);
|
||||
@ -402,6 +427,8 @@ void TerramanLibrary::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_prop_material_cache_get_key", "chunk"), &TerramanLibrary::_prop_material_cache_get_key);
|
||||
ClassDB::bind_method(D_METHOD("prop_material_cache_get", "key"), &TerramanLibrary::prop_material_cache_get);
|
||||
ClassDB::bind_method(D_METHOD("_prop_material_cache_get", "key"), &TerramanLibrary::_prop_material_cache_get);
|
||||
ClassDB::bind_method(D_METHOD("prop_material_cache_unref", "key"), &TerramanLibrary::prop_material_cache_unref);
|
||||
ClassDB::bind_method(D_METHOD("_prop_material_cache_unref", "key"), &TerramanLibrary::_prop_material_cache_unref);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("prop_material_add", "value"), &TerramanLibrary::prop_material_add);
|
||||
ClassDB::bind_method(D_METHOD("prop_material_set", "index", "value"), &TerramanLibrary::prop_material_set);
|
||||
|
@ -76,6 +76,8 @@ public:
|
||||
virtual void _material_cache_get_key(Ref<TerraChunk> chunk);
|
||||
Ref<TerraMaterialCache> material_cache_get(const int key);
|
||||
virtual Ref<TerraMaterialCache> _material_cache_get(const int key);
|
||||
void material_cache_unref(const int key);
|
||||
virtual void _material_cache_unref(const int key);
|
||||
|
||||
void material_add(const Ref<Material> &value);
|
||||
void material_set(const int index, const Ref<Material> &value);
|
||||
@ -93,6 +95,8 @@ public:
|
||||
virtual void _liquid_material_cache_get_key(Ref<TerraChunk> chunk);
|
||||
Ref<TerraMaterialCache> liquid_material_cache_get(const int key);
|
||||
virtual Ref<TerraMaterialCache> _liquid_material_cache_get(const int key);
|
||||
void liquid_material_cache_unref(const int key);
|
||||
virtual void _liquid_material_cache_unref(const int key);
|
||||
|
||||
void liquid_material_add(const Ref<Material> &value);
|
||||
void liquid_material_set(const int index, const Ref<Material> &value);
|
||||
@ -110,6 +114,8 @@ public:
|
||||
virtual void _prop_material_cache_get_key(Ref<TerraChunk> chunk);
|
||||
Ref<TerraMaterialCache> prop_material_cache_get(const int key);
|
||||
virtual Ref<TerraMaterialCache> _prop_material_cache_get(const int key);
|
||||
void prop_material_cache_unref(const int key);
|
||||
virtual void _prop_material_cache_unref(const int key);
|
||||
|
||||
void prop_material_add(const Ref<Material> &value);
|
||||
void prop_material_set(const int index, const Ref<Material> &value);
|
||||
@ -157,9 +163,9 @@ protected:
|
||||
static void _bind_methods();
|
||||
|
||||
bool _initialized;
|
||||
Vector<Ref<Material> > _materials;
|
||||
Vector<Ref<Material> > _liquid_materials;
|
||||
Vector<Ref<Material> > _prop_materials;
|
||||
Vector<Ref<Material>> _materials;
|
||||
Vector<Ref<Material>> _liquid_materials;
|
||||
Vector<Ref<Material>> _prop_materials;
|
||||
};
|
||||
|
||||
#endif // TERRA_LIBRARY_H
|
||||
|
@ -104,8 +104,14 @@ void TerramanLibraryMergerPCM::_material_cache_get_key(Ref<TerraChunk> chunk) {
|
||||
_cache_mutex.lock();
|
||||
|
||||
if (_material_cache.has(hash)) {
|
||||
Ref<TerraMaterialCachePCM> cc = _material_cache[hash];
|
||||
|
||||
if (cc.is_valid()) {
|
||||
cc->inc_ref_count();
|
||||
}
|
||||
|
||||
_cache_mutex.unlock();
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -113,6 +119,7 @@ void TerramanLibraryMergerPCM::_material_cache_get_key(Ref<TerraChunk> chunk) {
|
||||
|
||||
Ref<TerraMaterialCachePCM> cache;
|
||||
cache.instance();
|
||||
cache->inc_ref_count();
|
||||
|
||||
cache->set_texture_flags(get_texture_flags());
|
||||
cache->set_max_atlas_size(get_max_atlas_size());
|
||||
@ -171,6 +178,28 @@ Ref<TerraMaterialCache> TerramanLibraryMergerPCM::_material_cache_get(const int
|
||||
return _material_cache[key];
|
||||
}
|
||||
|
||||
void TerramanLibraryMergerPCM::_material_cache_unref(const int key) {
|
||||
_cache_mutex.lock();
|
||||
|
||||
if (!_material_cache.has(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<TerraMaterialCachePCM> cc = _material_cache[key];
|
||||
|
||||
if (!cc.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
cc->dec_ref_count();
|
||||
|
||||
if (cc->get_ref_count() <= 0) {
|
||||
_material_cache.erase(key);
|
||||
}
|
||||
|
||||
_cache_mutex.unlock();
|
||||
}
|
||||
|
||||
int TerramanLibraryMergerPCM::get_texture_flags() const {
|
||||
return _packer->get_texture_flags();
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
bool _supports_caching();
|
||||
void _material_cache_get_key(Ref<TerraChunk> chunk);
|
||||
Ref<TerraMaterialCache> _material_cache_get(const int key);
|
||||
void _material_cache_unref(const int key);
|
||||
|
||||
int get_texture_flags() const;
|
||||
void set_texture_flags(const int flags);
|
||||
|
@ -938,6 +938,12 @@ void TerraChunk::enter_tree() {
|
||||
void TerraChunk::exit_tree() {
|
||||
_is_in_tree = false;
|
||||
|
||||
if (_library.is_valid() && _library->supports_caching()) {
|
||||
if (material_cache_key_has()) {
|
||||
_library->material_cache_unref(material_cache_key_get());
|
||||
}
|
||||
}
|
||||
|
||||
if (has_method("_exit_tree"))
|
||||
call("_exit_tree");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user