godot: Crash on do `OS::set_window_size(Vector2(1024, 680))` when changing scene

Godot version:

3.0

OS/device including version:

MacBook Pro (Retina, 13-inch, Early 2015) macOS 10.14.2 OpenGL ES 3.0 Renderer: Intel® Iris™ Graphics 6100

Issue description:

I’m in GDNative cpp. Program crash on OS::set_window_size when changing to another scene with owner->get_tree()->change_scene("res://AnotherScene.tscn");. The target scene’s base node code exmaple:

void LVBase::_ready()
{
	OS::set_window_size(Vector2(1024, 680));
}

Steps to reproduce: Given a GDNative base node of a Scene, a Node2D

#ifndef _LSBASE_H
#define _LSBASE_H

#include <Godot.hpp>
#include <Node2D.hpp>
#include <String.hpp>

using namespace godot;

class LSBase : public GodotScript<Node2D>
{
    GODOT_CLASS(LSBase);
public:
    LSBase() { }

    void _ready()
    {
        OS::set_window_size(Vector2(640, 438));
        OS::center_window();
    }

    void _process(float delta);

    static void _register_methods() {
        register_method("_ready", &LSBase::_ready);
        register_method("_process", &LSBase::_process);
    }
};

#endif

And another base node of another scene:

#ifndef _LVBASE_H
#define _LVBASE_H

#include <Godot.hpp>
#include <Node2D.hpp>
#include <String.hpp>

#include "WilDataLibrary.h"

using namespace godot;

class LVBase : public GodotScript<Node2D>
{
    GODOT_CLASS(LVBase);
public:
    LVBase() { }

    WilDataLibrary* WilDataLib = nullptr;

	void _ready()
    {
        OS::set_window_size(Vector2(1024, 680));
    }
    void _process(float delta);


    static void _register_methods() {
        register_method("_ready", &LVBase::_ready);
        register_method("_process", &LVBase::_process);
    }
};

#endif

change scene from one to another like:

    owner->get_tree()->change_scene("res://AnotherScene.tscn");

Minimal reproduction project:

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 21 (16 by maintainers)

Commits related to this issue

Most upvoted comments

Simple interlocking of iteration() call fixes this and #23572 for me.

I assume there’s no reason to add real mutex since this lock is single-threaded and only serve to prevent recursive iteration() calls.

diff --git a/main/main.cpp b/main/main.cpp
index e0f9cfb9d..d83e295da 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1786,6 +1786,7 @@ uint64_t Main::target_ticks = 0;
 uint32_t Main::frames = 0;
 uint32_t Main::frame = 0;
 bool Main::force_redraw_requested = false;
+bool Main::iteration_finished = true;
 
 // For performance metrics
 static uint64_t physics_process_max = 0;
@@ -1793,6 +1794,11 @@ static uint64_t idle_process_max = 0;
 
 bool Main::iteration() {
 
+	if (!iteration_finished)
+		return false;
+
+	iteration_finished = false;
+
 	uint64_t ticks = OS::get_singleton()->get_ticks_usec();
 	Engine::get_singleton()->_frame_ticks = ticks;
 	main_timer_sync.set_cpu_ticks_usec(ticks);
@@ -1920,8 +1926,10 @@ bool Main::iteration() {
 		frames = 0;
 	}
 
-	if (fixed_fps != -1)
+	if (fixed_fps != -1) {
+		iteration_finished = true;
 		return exit;
+	}
 
 	if (OS::get_singleton()->is_in_low_processor_usage_mode() || !OS::get_singleton()->can_draw())
 		OS::get_singleton()->delay_usec(OS::get_singleton()->get_low_processor_usage_mode_sleep_usec()); //apply some delay to force idle time (results in about 60 FPS max)
@@ -1945,11 +1953,13 @@ bool Main::iteration() {
 	if (auto_build_solutions) {
 		auto_build_solutions = false;
 		if (!EditorNode::get_singleton()->call_build()) {
+			iteration_finished = true;
 			ERR_FAIL_V(true);
 		}
 	}
 #endif
 
+	iteration_finished = true;
 	return exit || auto_quit;
 }
 
diff --git a/main/main.h b/main/main.h
index 01fc259a8..7e4b79e3d 100644
--- a/main/main.h
+++ b/main/main.h
@@ -47,6 +47,7 @@ class Main {
 	static uint32_t frames;
 	static uint32_t frame;
 	static bool force_redraw_requested;
+	static bool iteration_finished;
 
 public:
 	static bool is_project_manager();

Would be very appreciated if you include operating system in your report, else it will be difficult to test