Browse Source

Merge pull request #98451 from RandomShaper/ext_text_err

ExternalTexture: Avoid error when destroyed without having been used
Thaddeus Crews 10 months ago
parent
commit
e3751721af
2 changed files with 26 additions and 2 deletions
  1. 22 1
      scene/resources/external_texture.cpp
  2. 4 1
      scene/resources/external_texture.h

+ 22 - 1
scene/resources/external_texture.cpp

@@ -39,12 +39,14 @@ void ExternalTexture::_bind_methods() {
 }
 }
 
 
 uint64_t ExternalTexture::get_external_texture_id() const {
 uint64_t ExternalTexture::get_external_texture_id() const {
+	_ensure_created();
 	return RenderingServer::get_singleton()->texture_get_native_handle(texture);
 	return RenderingServer::get_singleton()->texture_get_native_handle(texture);
 }
 }
 
 
 void ExternalTexture::set_size(const Size2 &p_size) {
 void ExternalTexture::set_size(const Size2 &p_size) {
 	if (p_size.width > 0 && p_size.height > 0 && p_size != size) {
 	if (p_size.width > 0 && p_size.height > 0 && p_size != size) {
 		size = p_size;
 		size = p_size;
+		_ensure_created();
 		RenderingServer::get_singleton()->texture_external_update(texture, size.width, size.height, external_buffer);
 		RenderingServer::get_singleton()->texture_external_update(texture, size.width, size.height, external_buffer);
 		emit_changed();
 		emit_changed();
 	}
 	}
@@ -57,6 +59,7 @@ Size2 ExternalTexture::get_size() const {
 void ExternalTexture::set_external_buffer_id(uint64_t p_external_buffer) {
 void ExternalTexture::set_external_buffer_id(uint64_t p_external_buffer) {
 	if (p_external_buffer != external_buffer) {
 	if (p_external_buffer != external_buffer) {
 		external_buffer = p_external_buffer;
 		external_buffer = p_external_buffer;
+		_ensure_created();
 		RenderingServer::get_singleton()->texture_external_update(texture, size.width, size.height, external_buffer);
 		RenderingServer::get_singleton()->texture_external_update(texture, size.width, size.height, external_buffer);
 	}
 	}
 }
 }
@@ -74,11 +77,29 @@ bool ExternalTexture::has_alpha() const {
 }
 }
 
 
 RID ExternalTexture::get_rid() const {
 RID ExternalTexture::get_rid() const {
+	if (!texture.is_valid()) {
+		texture = RenderingServer::get_singleton()->texture_2d_placeholder_create();
+		using_placeholder = true;
+	}
 	return texture;
 	return texture;
 }
 }
 
 
+void ExternalTexture::_ensure_created() const {
+	if (texture.is_valid() && !using_placeholder) {
+		return;
+	}
+
+	RID new_texture = RenderingServer::get_singleton()->texture_external_create(size.width, size.height);
+	if (using_placeholder) {
+		DEV_ASSERT(texture.is_valid());
+		RenderingServer::get_singleton()->texture_replace(texture, new_texture);
+		using_placeholder = false;
+	} else {
+		texture = new_texture;
+	}
+}
+
 ExternalTexture::ExternalTexture() {
 ExternalTexture::ExternalTexture() {
-	texture = RenderingServer::get_singleton()->texture_external_create(size.width, size.height);
 }
 }
 
 
 ExternalTexture::~ExternalTexture() {
 ExternalTexture::~ExternalTexture() {

+ 4 - 1
scene/resources/external_texture.h

@@ -38,10 +38,13 @@ class ExternalTexture : public Texture2D {
 	GDCLASS(ExternalTexture, Texture2D);
 	GDCLASS(ExternalTexture, Texture2D);
 
 
 private:
 private:
-	RID texture;
+	mutable RID texture;
+	mutable bool using_placeholder = false;
 	Size2 size = Size2(256, 256);
 	Size2 size = Size2(256, 256);
 	uint64_t external_buffer = 0;
 	uint64_t external_buffer = 0;
 
 
+	void _ensure_created() const;
+
 protected:
 protected:
 	static void _bind_methods();
 	static void _bind_methods();