Implement a cleaner (and better) way to save imagedata from ImageTexture, fixes #18801
This commit is contained in:
parent
5784caae73
commit
8b231b96e3
@ -1666,7 +1666,20 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
|
|||||||
|
|
||||||
if (E->get().usage & PROPERTY_USAGE_STORAGE) {
|
if (E->get().usage & PROPERTY_USAGE_STORAGE) {
|
||||||
|
|
||||||
_find_resources(res->get(E->get().name));
|
Variant value = res->get(E->get().name);
|
||||||
|
if (E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
|
||||||
|
RES sres = value;
|
||||||
|
if (sres.is_valid()) {
|
||||||
|
NonPersistentKey npk;
|
||||||
|
npk.base = res;
|
||||||
|
npk.property = E->get().name;
|
||||||
|
non_persistent_map[npk] = sres;
|
||||||
|
resource_set.insert(sres);
|
||||||
|
saved_resources.push_back(sres);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_find_resources(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1810,7 +1823,17 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
|
|||||||
if ((F->get().usage & PROPERTY_USAGE_STORAGE)) {
|
if ((F->get().usage & PROPERTY_USAGE_STORAGE)) {
|
||||||
Property p;
|
Property p;
|
||||||
p.name_idx = get_string_index(F->get().name);
|
p.name_idx = get_string_index(F->get().name);
|
||||||
p.value = E->get()->get(F->get().name);
|
|
||||||
|
if (F->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
|
||||||
|
NonPersistentKey npk;
|
||||||
|
npk.base = E->get();
|
||||||
|
npk.property = F->get().name;
|
||||||
|
if (non_persistent_map.has(npk)) {
|
||||||
|
p.value = non_persistent_map[npk];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p.value = E->get()->get(F->get().name);
|
||||||
|
}
|
||||||
|
|
||||||
Variant default_value = ClassDB::class_get_default_property_value(E->get()->get_class(), F->get().name);
|
Variant default_value = ClassDB::class_get_default_property_value(E->get()->get_class(), F->get().name);
|
||||||
|
|
||||||
|
@ -123,6 +123,14 @@ class ResourceFormatSaverBinaryInstance {
|
|||||||
FileAccess *f;
|
FileAccess *f;
|
||||||
String magic;
|
String magic;
|
||||||
Set<RES> resource_set;
|
Set<RES> resource_set;
|
||||||
|
|
||||||
|
struct NonPersistentKey { //for resource properties generated on the fly
|
||||||
|
RES base;
|
||||||
|
StringName property;
|
||||||
|
bool operator<(const NonPersistentKey &p_key) const { return base == p_key.base ? property < p_key.property : base < p_key.base; }
|
||||||
|
};
|
||||||
|
|
||||||
|
Map<NonPersistentKey, RES> non_persistent_map;
|
||||||
Map<StringName, int> string_map;
|
Map<StringName, int> string_map;
|
||||||
Vector<StringName> strings;
|
Vector<StringName> strings;
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ enum PropertyUsageFlags {
|
|||||||
PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 << 21, // If the object is duplicated also this property will be duplicated
|
PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 << 21, // If the object is duplicated also this property will be duplicated
|
||||||
PROPERTY_USAGE_HIGH_END_GFX = 1 << 22,
|
PROPERTY_USAGE_HIGH_END_GFX = 1 << 22,
|
||||||
PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 23,
|
PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 23,
|
||||||
|
PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 24,
|
||||||
|
|
||||||
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
|
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
|
||||||
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
|
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
|
||||||
|
@ -4781,8 +4781,6 @@ EditorNode::EditorNode() {
|
|||||||
ResourceLoader::clear_translation_remaps(); //no remaps using during editor
|
ResourceLoader::clear_translation_remaps(); //no remaps using during editor
|
||||||
ResourceLoader::clear_path_remaps();
|
ResourceLoader::clear_path_remaps();
|
||||||
|
|
||||||
ImageTexture::set_keep_images_cached(true);
|
|
||||||
|
|
||||||
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
|
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
|
||||||
|
|
||||||
if (id) {
|
if (id) {
|
||||||
|
@ -1408,7 +1408,21 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
|
|||||||
if (pi.usage & PROPERTY_USAGE_STORAGE) {
|
if (pi.usage & PROPERTY_USAGE_STORAGE) {
|
||||||
|
|
||||||
Variant v = res->get(I->get().name);
|
Variant v = res->get(I->get().name);
|
||||||
_find_resources(v);
|
|
||||||
|
if (pi.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
|
||||||
|
RES sres = v;
|
||||||
|
if (sres.is_valid()) {
|
||||||
|
NonPersistentKey npk;
|
||||||
|
npk.base = res;
|
||||||
|
npk.property = pi.name;
|
||||||
|
non_persistent_map[npk] = sres;
|
||||||
|
resource_set.insert(sres);
|
||||||
|
saved_resources.push_back(sres);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_find_resources(v);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
I = I->next();
|
I = I->next();
|
||||||
@ -1600,7 +1614,17 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
|
|||||||
if (PE->get().usage & PROPERTY_USAGE_STORAGE) {
|
if (PE->get().usage & PROPERTY_USAGE_STORAGE) {
|
||||||
|
|
||||||
String name = PE->get().name;
|
String name = PE->get().name;
|
||||||
Variant value = res->get(name);
|
Variant value;
|
||||||
|
if (PE->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
|
||||||
|
NonPersistentKey npk;
|
||||||
|
npk.base = res;
|
||||||
|
npk.property = name;
|
||||||
|
if (non_persistent_map.has(npk)) {
|
||||||
|
value = non_persistent_map[npk];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = res->get(name);
|
||||||
|
}
|
||||||
Variant default_value = ClassDB::class_get_default_property_value(res->get_class(), name);
|
Variant default_value = ClassDB::class_get_default_property_value(res->get_class(), name);
|
||||||
|
|
||||||
if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) {
|
if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) {
|
||||||
|
@ -155,6 +155,15 @@ class ResourceFormatSaverTextInstance {
|
|||||||
bool bundle_resources;
|
bool bundle_resources;
|
||||||
bool skip_editor;
|
bool skip_editor;
|
||||||
FileAccess *f;
|
FileAccess *f;
|
||||||
|
|
||||||
|
struct NonPersistentKey { //for resource properties generated on the fly
|
||||||
|
RES base;
|
||||||
|
StringName property;
|
||||||
|
bool operator<(const NonPersistentKey &p_key) const { return base == p_key.base ? property < p_key.property : base < p_key.base; }
|
||||||
|
};
|
||||||
|
|
||||||
|
Map<NonPersistentKey, RES> non_persistent_map;
|
||||||
|
|
||||||
Set<RES> resource_set;
|
Set<RES> resource_set;
|
||||||
List<RES> saved_resources;
|
List<RES> saved_resources;
|
||||||
Map<RES, int> external_resources;
|
Map<RES, int> external_resources;
|
||||||
|
@ -157,7 +157,7 @@ bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
|
|||||||
void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
|
void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat"));
|
p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat"));
|
||||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
|
p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
|
||||||
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
|
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,12 +178,6 @@ void ImageTexture::_reload_hook(const RID &p_hook) {
|
|||||||
_change_notify();
|
_change_notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageTexture::keep_images_cached = false;
|
|
||||||
|
|
||||||
void ImageTexture::set_keep_images_cached(bool p_enable) {
|
|
||||||
keep_images_cached = p_enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
|
void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
|
||||||
|
|
||||||
flags = p_flags;
|
flags = p_flags;
|
||||||
@ -205,9 +199,7 @@ void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags
|
|||||||
VisualServer::get_singleton()->texture_set_data(texture, p_image);
|
VisualServer::get_singleton()->texture_set_data(texture, p_image);
|
||||||
_change_notify();
|
_change_notify();
|
||||||
|
|
||||||
if (keep_images_cached) {
|
image_stored = true;
|
||||||
image_cache = p_image;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageTexture::set_flags(uint32_t p_flags) {
|
void ImageTexture::set_flags(uint32_t p_flags) {
|
||||||
@ -255,10 +247,7 @@ void ImageTexture::set_data(const Ref<Image> &p_image) {
|
|||||||
|
|
||||||
_change_notify();
|
_change_notify();
|
||||||
alpha_cache.unref();
|
alpha_cache.unref();
|
||||||
|
image_stored = true;
|
||||||
if (keep_images_cached) {
|
|
||||||
image_cache = p_image;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageTexture::_resource_path_changed() {
|
void ImageTexture::_resource_path_changed() {
|
||||||
@ -268,10 +257,10 @@ void ImageTexture::_resource_path_changed() {
|
|||||||
|
|
||||||
Ref<Image> ImageTexture::get_data() const {
|
Ref<Image> ImageTexture::get_data() const {
|
||||||
|
|
||||||
if (image_cache.is_valid()) {
|
if (image_stored) {
|
||||||
return image_cache;
|
|
||||||
} else {
|
|
||||||
return VisualServer::get_singleton()->texture_get_data(texture);
|
return VisualServer::get_singleton()->texture_get_data(texture);
|
||||||
|
} else {
|
||||||
|
return Ref<Image>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ private:
|
|||||||
Size2 size_override;
|
Size2 size_override;
|
||||||
float lossy_storage_quality;
|
float lossy_storage_quality;
|
||||||
mutable Ref<BitMap> alpha_cache;
|
mutable Ref<BitMap> alpha_cache;
|
||||||
Ref<Image> image_cache;
|
bool image_stored;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void reload_from_file();
|
virtual void reload_from_file();
|
||||||
@ -126,11 +126,7 @@ protected:
|
|||||||
|
|
||||||
void _set_data(Dictionary p_data);
|
void _set_data(Dictionary p_data);
|
||||||
|
|
||||||
static bool keep_images_cached;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void set_keep_images_cached(bool p_enable);
|
|
||||||
|
|
||||||
void create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT);
|
void create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT);
|
||||||
void create_from_image(const Ref<Image> &p_image, uint32_t p_flags = FLAGS_DEFAULT);
|
void create_from_image(const Ref<Image> &p_image, uint32_t p_flags = FLAGS_DEFAULT);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user