Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix flickering in embedded game when paused #102006

Merged
merged 1 commit into from
Jan 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fix flickering in embedded game when paused
Hilderin committed Jan 27, 2025
commit 3580509fee8828ee219ac4836cacde79175bda72
54 changes: 43 additions & 11 deletions editor/plugins/game_view_plugin.cpp
Original file line number Diff line number Diff line change
@@ -301,6 +301,7 @@ void GameView::_stop_pressed() {
}

_detach_script_debugger();
paused = false;

EditorNode::get_singleton()->set_unfocused_low_processor_usage_mode_enabled(true);
embedded_process->reset();
@@ -515,15 +516,26 @@ void GameView::_update_embed_menu_options() {
}

void GameView::_update_embed_window_size() {
if (embed_size_mode == SIZE_MODE_FIXED || embed_size_mode == SIZE_MODE_KEEP_ASPECT) {
//The embedded process control will need the desired window size.
EditorRun::WindowPlacement placement = EditorRun::get_window_placement();
embedded_process->set_window_size(placement.size);
if (paused) {
// When paused, Godot does not re-render. As a result, resizing the game window to a larger size
// causes artifacts and flickering. However, resizing to a smaller size seems fine.
// To prevent artifacts and flickering, we will force the game window to maintain its size.
// Using the same technique as SIZE_MODE_FIXED, the embedded process control will
// prevent resizing the game to a larger size while maintaining the aspect ratio.
embedded_process->set_window_size(size_paused);
embedded_process->set_keep_aspect(false);

} else {
//Stretch... No need for the window size.
embedded_process->set_window_size(Size2i());
if (embed_size_mode == SIZE_MODE_FIXED || embed_size_mode == SIZE_MODE_KEEP_ASPECT) {
// The embedded process control will need the desired window size.
EditorRun::WindowPlacement placement = EditorRun::get_window_placement();
embedded_process->set_window_size(placement.size);
} else {
// Stretch... No need for the window size.
embedded_process->set_window_size(Size2i());
}
embedded_process->set_keep_aspect(embed_size_mode == SIZE_MODE_KEEP_ASPECT);
}
embedded_process->set_keep_aspect(embed_size_mode == SIZE_MODE_KEEP_ASPECT);
}

void GameView::_hide_selection_toggled(bool p_pressed) {
@@ -787,14 +799,29 @@ void GameView::_window_close_request() {
embedded_process->reset();

// When the embedding is not complete, we need to kill the process.
if (embedded_process->is_embedding_in_progress()) {
// If the game is paused, the close request will not be processed by the game, so it's better to kill the process.
if (paused || embedded_process->is_embedding_in_progress()) {
// Call deferred to prevent the _stop_pressed callback to be executed before the wrapper window
// actually closes.
callable_mp(EditorRunBar::get_singleton(), &EditorRunBar::stop_playing).call_deferred();
}
}
}

void GameView::_debugger_breaked(bool p_breaked, bool p_can_debug) {
if (p_breaked == paused) {
return;
}

paused = p_breaked;

if (paused) {
size_paused = embedded_process->get_screen_embedded_window_rect().size;
}

_update_embed_window_size();
}

GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
singleton = this;

@@ -984,6 +1011,8 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
p_wrapper->set_override_close_request(true);
p_wrapper->connect("window_close_requested", callable_mp(this, &GameView::_window_close_request));
p_wrapper->connect("window_size_changed", callable_mp(this, &GameView::_update_floating_window_settings));

EditorDebuggerNode::get_singleton()->connect("breaked", callable_mp(this, &GameView::_debugger_breaked));
}

///////
@@ -1053,15 +1082,18 @@ void GameViewPlugin::_window_visibility_changed(bool p_visible) {
}

void GameViewPlugin::_save_last_editor(const String &p_editor) {
if (p_editor != get_name()) {
if (p_editor != get_plugin_name()) {
last_editor = p_editor;
}
}

void GameViewPlugin::_focus_another_editor() {
if (window_wrapper->get_window_enabled()) {
ERR_FAIL_COND(last_editor.is_empty());
EditorInterface::get_singleton()->set_main_screen_editor(last_editor);
if (last_editor.is_empty()) {
EditorNode::get_singleton()->get_editor_main_screen()->select(EditorMainScreen::EDITOR_2D);
} else {
EditorInterface::get_singleton()->set_main_screen_editor(last_editor);
}
}
}

4 changes: 4 additions & 0 deletions editor/plugins/game_view_plugin.h
Original file line number Diff line number Diff line change
@@ -122,6 +122,8 @@ class GameView : public VBoxContainer {
bool embed_on_play = true;
bool make_floating_on_play = true;
EmbedSizeMode embed_size_mode = SIZE_MODE_FIXED;
bool paused = false;
Size2 size_paused;

Rect2i floating_window_rect;
int floating_window_screen = -1;
@@ -186,6 +188,8 @@ class GameView : public VBoxContainer {
void _detach_script_debugger();
void _remote_window_title_changed(String title);

void _debugger_breaked(bool p_breaked, bool p_can_debug);

protected:
void _notification(int p_what);