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

Splash screen minimum display time does not work properly on macOS #68798

Closed
bmercury opened this issue Nov 17, 2022 · 6 comments · Fixed by #72307
Closed

Splash screen minimum display time does not work properly on macOS #68798

bmercury opened this issue Nov 17, 2022 · 6 comments · Fixed by #72307

Comments

@bmercury
Copy link

Godot version

4.0 beta 5

System information

MacOS Monterey M1

Issue description

Setting the "minimum display time" parameter in project settings under Application>Boot splash does not show the custom image (nor the default one) for that amount of time. Instead when the app is run either from an editor or the project manager, it waits until that time is over and then splashes for a very short time (as if no custom time was set)

This happens when run from the editor.
This happens when run from the project manager.

Steps to reproduce

  1. Create a new project
  2. Set a custom image for splash screen (or leave default)
  3. Set minimum display time to some notable duration (e.g 4 seconds / 4000ms )
  4. Run the project
  5. The game window is not visible (although shown in the doc)
  6. After the time is over (4s in this case) the window is finally shown with the custom splash image(visible for less than a second) and then loads the main scene

Minimal reproduction project

No response

@Calinou
Copy link
Member

Calinou commented Nov 17, 2022

If you have access to Windows or Linux machines, can you reproduce the issue there? Splash screen drawing is OS-specific.

@bmercury
Copy link
Author

If you have access to Windows or Linux machines, can you reproduce the issue there? Splash screen drawing is OS-specific.

Unfortunately I do not have other operating systems available at the moment.

@RumblingTurtle
Copy link
Contributor

If you have access to Windows or Linux machines, can you reproduce the issue there? Splash screen drawing is OS-specific.

Not reproducible on Ubuntu 20.04.4 LTS

@lostminds
Copy link

I get the same issue on macOS 13, Godot 4.0.beta7. I set the minimum_display_time to try out and see how a custom boot splash image would appear, but at least on macOS it seems that the wait time that property controls happens before the game window is displayed on screen like @bmercury described.

It seems that this delay is happening in

godot/main/main.cpp

Lines 3062 to 3068 in 829d49b

if (minimum_time_msec) {
uint64_t minimum_time = 1000 * minimum_time_msec;
uint64_t elapsed_time = OS::get_singleton()->get_ticks_usec();
if (elapsed_time < minimum_time) {
OS::get_singleton()->delay_usec(minimum_time - elapsed_time);
}
}
which is after the window has been created. But perhaps on macOS the system window server has not yet had time to move the window on screen when the delay happens so it's not visible?

@Calinou
Copy link
Member

Calinou commented Dec 7, 2022

For reference, this feature was implemented in #41833.

cc @dalexeev

@Calinou Calinou changed the title Splash screen minimum display time does not work properly Splash screen minimum display time does not work properly on macOS Dec 7, 2022
@dalexeev
Copy link
Member

dalexeev commented Dec 7, 2022

I don't have access to macOS and don't know Godot core, but here's what I found.

The boot splash delay occurs at the end of Main::start.

godot/main/main.cpp

Lines 3062 to 3068 in a7937fe

if (minimum_time_msec) {
uint64_t minimum_time = 1000 * minimum_time_msec;
uint64_t elapsed_time = OS::get_singleton()->get_ticks_usec();
if (elapsed_time < minimum_time) {
OS::get_singleton()->delay_usec(minimum_time - elapsed_time);
}
}

This function is called in the corresponding main for different platforms.

Details

err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]);
if (err == ERR_HELP) { // Returned by --help and --version, so success.
return 0;
} else if (err != OK) {
return 255;
}
if (Main::start()) {
os.run(); // It is actually the OS that decides how to run.
}
Main::cleanup();

Error err = Main::setup(argv[0], argc - 1, &argv[1]);
if (err != OK) {
free(cwd);
if (err == ERR_HELP) { // Returned by --help and --version, so success.
return 0;
}
return 255;
}
if (Main::start()) {
os.set_exit_code(EXIT_SUCCESS);
os.run(); // it is actually the OS that decides how to run
}
Main::cleanup();

Error err = Main::setup(argv_utf8[0], argc - 1, &argv_utf8[1]);
if (err != OK) {
for (int i = 0; i < argc; ++i) {
delete[] argv_utf8[i];
}
delete[] argv_utf8;
if (err == ERR_HELP) { // Returned by --help and --version, so success.
return 0;
}
return 255;
}
if (Main::start()) {
os.run();
}
Main::cleanup();

Inside which the MainLoop functions are called.

Details

void OS_MacOS::run() {
if (!main_loop) {
return;
}
main_loop->initialize();
bool quit = false;
while (!quit) {
@try {
if (DisplayServer::get_singleton()) {
DisplayServer::get_singleton()->process_events(); // Get rid of pending events.
}
joypad_macos->process_joypads();
if (Main::iteration()) {
quit = true;
}
} @catch (NSException *exception) {
ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String));
}
}
main_loop->finalize();
}

void OS_LinuxBSD::run() {
if (!main_loop) {
return;
}
main_loop->initialize();
//uint64_t last_ticks=get_ticks_usec();
//int frames=0;
//uint64_t frame=0;
while (true) {
DisplayServer::get_singleton()->process_events(); // get rid of pending events
#ifdef JOYDEV_ENABLED
joypad->process_joypads();
#endif
if (Main::iteration()) {
break;
}
}
main_loop->finalize();
}

void OS_Windows::run() {
if (!main_loop) {
return;
}
main_loop->initialize();
while (true) {
DisplayServer::get_singleton()->process_events(); // get rid of pending events
if (Main::iteration()) {
break;
}
}
main_loop->finalize();
}

MainLoop::initialize() is the same for all platforms.

void MainLoop::initialize() {
if (initialize_script.is_valid()) {
set_script(initialize_script);
}
GDVIRTUAL_CALL(_initialize);
}

I guess there is some difference between platforms in

if (Main::start()) { 
    os.run();
} 

That is, on MacOS something is called in os.run(), and on other platforms in Main::start() or earlier. But comparing these files, I did not notice any clues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants