Open abb128 opened 3 years ago
Another use case for this is performing offline rendering while the window is minimized.
Now that tray icons are on the way (godotengine/godot#80211) this would be even more useful, since for VR overlays we could hide the window away entirely.
This is now possible using DisplayServer::register_additional_output
: https://github.com/godotengine/godot/pull/94412
@Calinou I am using Game Capture, but there aren't any options for capturing minimized windows.
Some Unity programs like VSeeFace keep rendering while minimized with Game Capture without any extra set up in OBS.
In vulkan_context.cpp:
if (window->width == 0 || window->height == 0) {
free(presentModes);
// Likely window minimized, no swapchain created.
return ERR_SKIP;
}
I've tried to change it so it creates a swapchain for rendering in minimized windows, but now it doesn't let me un-minimize the window back:
if (window->width == 0 || window->height == 0) {
swapchainExtent.width = 1152;
swapchainExtent.height = 648;
window->width = 1152;
window->height = 648;
}
@Calinou Apart from can_any_window_draw()
, there's another function in display_server_windows.cpp:
bool DisplayServerWindows::window_can_draw(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), false);
const WindowData &wd = windows[p_window];
return !wd.minimized;
}
After changing it to return true
always, the window still doesn't update when minimized.
I wonder if this is something that requires https://github.com/godotengine/godot-proposals/issues/5692 to work with Vulkan.
@Calinou How so?
@Calinou How so?
I don't know, I'm just guessing here 🙂
@dsnopek What are your thoughts on what could be causing this? (Mentioning since you added the minimized rendering feature)
@pochoco24 I don't know. The feature I worked on was specifically to fix a VR-related issue, which is fixed by the work I did. Like I said in previous comment (which I can't seem to find right now - this conversation is spread across a few places), I suspect there's something special that needs to be done for Windows or OBS, but I don't personally know what. Someone will need to do the research and some experimentation!
@Calinou @dsnopek From the OBS Documentation, OBS directly captures the DirectX or OpenGL of the game, and it also supports Vulkan.
Do you know what files handle Vulkan (Forward+) or OpenGL 3 (Compatibility) so I can check them out?
The Vulkan context is created in drivers/vulkan/rendering_context_driver_vulkan.cpp
, with some Windows-specific code in platform/windows/rendering_context_driver_vulkan_windows.cpp
.
The OpenGL context is created in platform/windows/gl_manager_windows_native.cpp
on Windows.
@Calinou In gl_manager_windows_native.cpp
, there's a function that gets called every frame, even if the window is minimized:
void GLManagerNative_Windows::swap_buffers() {
SwapBuffers(_current_window->hDC);
}
I want to check if SwapBuffers() has something that prevents minimized rendering, but VSCode can't find any references to SwapBuffers
in any file 🤔
SwapBuffers()
is a Windows API function: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-swapbuffers
@Calinou I managed to get it working (kind of) with a bare-bones Vulkan renderer. I just removed the handling minimization snippet and ensured that the swapchain renders at window resolution.
https://github.com/user-attachments/assets/194d0f43-7899-4522-b5e0-9b16a634cd7f
Since VSeeFace can do minimized rendering and uses DX11 with a DXGI swapchain, someone ran the demo by layering a DXGI swapchain with driver settings:
and they said it works just fine, but it still complains about being out-of-date. Using an actual DXGI swapchain in Godot would be the way to go, so your initial guess was right! #5692
@Calinou ITS FIXED NOW!! It works specifically for Windows using Direct3D 12 on the new Godot 4.3 build
In the source code, go to file rendering_device_driver_d3d12.cpp and change the line 2506 from:
res = swap_chain->d3d_swap_chain->ResizeBuffers(p_desired_framebuffer_count, 0, 0, DXGI_FORMAT_UNKNOWN, creation_flags);
to:
res = swap_chain->d3d_swap_chain->ResizeBuffers(p_desired_framebuffer_count, surface->width, surface->height, DXGI_FORMAT_UNKNOWN, creation_flags);
In Godot Project Settings set the Renderer Device to d3d12 (for windows), then, make a script that registers an additional output so it keeps rendering even when there are no visible windows available:
extends Node
var object = Object.new()
func _ready() -> void:
DisplayServer.register_additional_output(object)
# Free the object before closing the game
func _notification(what: int) -> void:
if what == NOTIFICATION_WM_CLOSE_REQUEST:
object.free()
Now when minimizing the window, it keeps rendering.
@Calinou ITS FIXED NOW!! It works specifically for Windows using Direct3D 12 on the new Godot 4.3 build
Hi, since a fix got found. Would it be possible to have this feature as a project settings toggle maybe? I personally need it too since I am working on a Vtubing software which needs stuff top stay rendering when the window is minimized. I think the feature could be useful for making other non-game based projects 👀
If this feature happen to get added, would you mind informing me?
Free the object before closing the game
@pochoco24, I was able to get the rendering to continue while Godot is minimized, but I'm wondering what the importance is of freeing the registered object before closing? Doesn't closing Godot just blow it away anyways, or is there something unsafe about leaving it?
Doesn't closing Godot just blow it away anyways, or is there something unsafe about leaving it?
Godot will print a warning on exit if you forget to free some resources before quitting, as it's bad practice. RefCounted handles this on its own, but manually managed resources such as RIDs don't.
Describe the project you are working on
An OpenVR dashboard overlay
Describe the problem or limitation you are having in your project
I am currently passing the texture of a Viewport to SteamVR through a GDNative module in order to create a dashboard. This dashboard is accessible within SteamVR and it can be viewed even if the window is minimized on the desktop, or even if there's no window at all.
In Windows Mixed Reality, entering VR mode can minimize all of your desktop windows depending on your settings, in order to improve performance for VR.
Godot Engine currently stops rendering if the window is minimized on desktop, presumably to avoid unnecessarily rendering:
( https://github.com/godotengine/godot/blob/3.2.3-stable/platform/windows/os_windows.cpp#L272 )
All of these factors combined make it so that my dashboard is useless and does not re-render unless the user manually makes sure to open the window on their desktop, so that the engine can continue rendering.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
The ability to override can_draw(), or even just an option to allow rendering while minimized, would allow the dashboard to continue rendering regardless of the state of the actual window.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
I'm unsure about how to actually design overriding that method (ideas would be appreciated), but one simpler solution would be to simply have a boolean project setting called
display/window/energy_saving/render_while_minimized
.If this enhancement will not be used often, can it be worked around with a few lines of script?
This is not scriptable functionality as it is part of the engine. For now, I had to build a custom version of the engine with the can_draw method above replaced with
Is there a reason why this should be core and not an add-on in the asset library?
See above