Jelajahi Sumber

Merge pull request #54621 from briansemrau/fix-preview-frame

Rémi Verschelde 3 tahun lalu
induk
melakukan
c7fefe50da

+ 27 - 23
editor/plugins/editor_preview_plugins.cpp

@@ -297,8 +297,14 @@ EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() {
 
 //////////////////////////////////////////////////////////////////
 
+void EditorMaterialPreviewPlugin::_generate_frame_started() {
+	RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
+
+	RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorMaterialPreviewPlugin *>(this), &EditorMaterialPreviewPlugin::_preview_done));
+}
+
 void EditorMaterialPreviewPlugin::_preview_done() {
-	preview_done.set();
+	preview_done.post();
 }
 
 bool EditorMaterialPreviewPlugin::handles(const String &p_type) const {
@@ -316,14 +322,9 @@ Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Si
 	if (material->get_shader_mode() == Shader::MODE_SPATIAL) {
 		RS::get_singleton()->mesh_surface_set_material(sphere, 0, material->get_rid());
 
-		RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
-
-		preview_done.clear();
-		RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorMaterialPreviewPlugin *>(this), &EditorMaterialPreviewPlugin::_preview_done));
+		RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorMaterialPreviewPlugin *>(this), &EditorMaterialPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
 
-		while (!preview_done.is_set()) {
-			OS::get_singleton()->delay_usec(10);
-		}
+		preview_done.wait();
 
 		Ref<Image> img = RS::get_singleton()->texture_2d_get(viewport_texture);
 		RS::get_singleton()->mesh_surface_set_material(sphere, 0, RID());
@@ -695,8 +696,14 @@ EditorAudioStreamPreviewPlugin::EditorAudioStreamPreviewPlugin() {
 
 ///////////////////////////////////////////////////////////////////////////
 
+void EditorMeshPreviewPlugin::_generate_frame_started() {
+	RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
+
+	RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorMeshPreviewPlugin *>(this), &EditorMeshPreviewPlugin::_preview_done));
+}
+
 void EditorMeshPreviewPlugin::_preview_done() {
-	preview_done.set();
+	preview_done.post();
 }
 
 bool EditorMeshPreviewPlugin::handles(const String &p_type) const {
@@ -727,14 +734,9 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2
 	xform.origin.z -= rot_aabb.size.z * 2;
 	RS::get_singleton()->instance_set_transform(mesh_instance, xform);
 
-	RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
+	RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorMeshPreviewPlugin *>(this), &EditorMeshPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
 
-	preview_done.clear();
-	RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorMeshPreviewPlugin *>(this), &EditorMeshPreviewPlugin::_preview_done));
-
-	while (!preview_done.is_set()) {
-		OS::get_singleton()->delay_usec(10);
-	}
+	preview_done.wait();
 
 	Ref<Image> img = RS::get_singleton()->texture_2d_get(viewport_texture);
 	ERR_FAIL_COND_V(img.is_null(), Ref<ImageTexture>());
@@ -806,8 +808,14 @@ EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() {
 
 ///////////////////////////////////////////////////////////////////////////
 
+void EditorFontPreviewPlugin::_generate_frame_started() {
+	RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
+
+	RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorFontPreviewPlugin *>(this), &EditorFontPreviewPlugin::_preview_done));
+}
+
 void EditorFontPreviewPlugin::_preview_done() {
-	preview_done.set();
+	preview_done.post();
 }
 
 bool EditorFontPreviewPlugin::handles(const String &p_type) const {
@@ -845,13 +853,9 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path,
 
 	font->draw_string(canvas_item, pos, sample, HALIGN_LEFT, -1.f, 50, Color(1, 1, 1));
 
-	preview_done.clear();
-	RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
-	RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<EditorFontPreviewPlugin *>(this), &EditorFontPreviewPlugin::_preview_done));
+	RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<EditorFontPreviewPlugin *>(this), &EditorFontPreviewPlugin::_generate_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
 
-	while (!preview_done.is_set()) {
-		OS::get_singleton()->delay_usec(10);
-	}
+	preview_done.wait();
 
 	RS::get_singleton()->canvas_item_clear(canvas_item);
 

+ 8 - 4
editor/plugins/editor_preview_plugins.h

@@ -92,8 +92,9 @@ class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator {
 	RID light2;
 	RID light_instance2;
 	RID camera;
-	mutable SafeFlag preview_done;
+	Semaphore preview_done;
 
+	void _generate_frame_started();
 	void _preview_done();
 
 public:
@@ -133,8 +134,9 @@ class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator {
 	RID light2;
 	RID light_instance2;
 	RID camera;
-	mutable SafeFlag preview_done;
+	Semaphore preview_done;
 
+	void _generate_frame_started();
 	void _preview_done();
 
 public:
@@ -152,8 +154,9 @@ class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator {
 	RID viewport_texture;
 	RID canvas;
 	RID canvas_item;
-	mutable SafeFlag preview_done;
+	Semaphore preview_done;
 
+	void _generate_frame_started();
 	void _preview_done();
 
 public:
@@ -168,8 +171,9 @@ public:
 class EditorTileMapPatternPreviewPlugin : public EditorResourcePreviewGenerator {
 	GDCLASS(EditorTileMapPatternPreviewPlugin, EditorResourcePreviewGenerator);
 
-	mutable SafeFlag preview_done;
+	Semaphore preview_done;
 
+	void _generate_frame_started();
 	void _preview_done();
 
 public:

+ 7 - 6
editor/plugins/tiles/tiles_editor_plugin.cpp

@@ -47,8 +47,12 @@
 
 TilesEditorPlugin *TilesEditorPlugin::singleton = nullptr;
 
+void TilesEditorPlugin::_preview_frame_started() {
+	RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_pattern_preview_done));
+}
+
 void TilesEditorPlugin::_pattern_preview_done() {
-	pattern_preview_done.set();
+	pattern_preview_done.post();
 }
 
 void TilesEditorPlugin::_thread_func(void *ud) {
@@ -112,12 +116,9 @@ void TilesEditorPlugin::_thread() {
 				// Add the viewport at the lasst moment to avoid rendering too early.
 				EditorNode::get_singleton()->add_child(viewport);
 
-				pattern_preview_done.clear();
-				RS::get_singleton()->request_frame_drawn_callback(callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_pattern_preview_done));
+				RS::get_singleton()->connect(SNAME("frame_pre_draw"), callable_mp(const_cast<TilesEditorPlugin *>(this), &TilesEditorPlugin::_preview_frame_started), Vector<Variant>(), Object::CONNECT_ONESHOT);
 
-				while (!pattern_preview_done.is_set()) {
-					OS::get_singleton()->delay_usec(10);
-				}
+				pattern_preview_done.wait();
 
 				Ref<Image> image = viewport->get_texture()->get_image();
 				Ref<ImageTexture> image_texture;

+ 2 - 1
editor/plugins/tiles/tiles_editor_plugin.h

@@ -77,7 +77,8 @@ private:
 	Thread pattern_preview_thread;
 	SafeFlag pattern_thread_exit;
 	SafeFlag pattern_thread_exited;
-	mutable SafeFlag pattern_preview_done;
+	Semaphore pattern_preview_done;
+	void _preview_frame_started();
 	void _pattern_preview_done();
 	static void _thread_func(void *ud);
 	void _thread();