Ebiten: on Windows 10 remote desktop not work.

Created on 20 Jul 2019  路  21Comments  路  Source: hajimehoshi/ebiten

I use Ebiten v1.9.3 and Golang 1.12 on Windows 10 Pro 1809.
The following error occurred when trying to display the Ebiten window on the remote desktop PC.

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x4f1262]

goroutine 1 [running, locked to thread]:
github.com/hajimehoshi/ebiten/internal/glfw.(*Window).GetMonitor(0x0, 0x0)
    D:/sample/vendor/github.com/hajimehoshi/ebiten/internal/glfw/glfw_windows.go:135 +0x42
github.com/hajimehoshi/ebiten/internal/ui.(*userInterface).currentMonitor(0xa5f180, 0x15decd4)
    D:/sample/vendor/github.com/hajimehoshi/ebiten/internal/ui/ui_glfw.go:955 +0x36
github.com/hajimehoshi/ebiten/internal/ui.glfwScale(0xc00005c2a8)
    D:/sample/vendor/github.com/hajimehoshi/ebiten/internal/ui/ui_windows.go:105 +0x34
github.com/hajimehoshi/ebiten/internal/ui.initialize(0xf, 0xc00009d140)
    D:/sample/vendor/github.com/hajimehoshi/ebiten/internal/ui/ui_glfw.go:116 +0x122
github.com/hajimehoshi/ebiten/internal/ui.init.0()
    D:/sample/vendor/github.com/hajimehoshi/ebiten/internal/ui/ui_glfw.go:89 +0x2e
bug external windows

Most helpful comment

No. I understand you suggested Vulkan instead of DirectX, but as Ebiten's graphics usage is very limited, I feel like using DirectX directly should be enough. Actually I've succeeded to port the graphics driver to Metal in Ebiten.

All 21 comments

Thank you for reporting! I'll take a look...

Looks like glfw.CreateWindow returns nil without errors. I'm not sure the reason 馃

It seems hard to fix this issue, maybe...

https://github.com/glfw/glfw/issues/1245

Windows virtual machines also might not support OpenGL/GLFW. Is there a way to force a different graphics driver, @hajimehoshi , or none at all? Output is going eventually to the web page for display, so let the browser worry about how to render the images.

mechanics of the problem, and a really lame workaround are here:

https://social.technet.microsoft.com/Forums/windowsserver/en-US/c8295ef8-3711-4576-9293-2c4965280165/opengl-and-remote-desktop?forum=winserverTS

quoting that forum thread:
~~~
When you start the OpenGL apps on the office PC using the
physically attached monitor and keyboard, the graphics card
may be checked by OpenGL - there are some OpenGL apps
that require physical hardware support and other OenGL apps
that are happy with rendering OpenGL in software. Both checks
are successful in this scenario and both flavors of OpenGL run
properly. Now you go to your home PC and establish a remote
connection to this user session. During the connection process,
the capabilities of the home PC's graphics card is sent to the host
PC in order to optimize the graphics output. This is required to
do some rendering on the receiver side rather than on the
sender side. This is done for GDI graphics primitives, but not
for openGL primitives. In your "remoting into existing user
session" scenario the OpenGL output on the host is sent to
the client pixel by pixel.

When you establish a new connection from a home PC to an
office PC, the home PC's graphics capabilities are relevant for
the user session. Such a remote session does not support
OpenGL in hardware - in other words, there is no 3D hardware
graphics support. This is why only the software OpenGL app
starts, but not the hardware OpenGL app. So your system
works as designed even if it sounds weird.

Note: In both scenarios all applications run on the office
PC. In the second scenario the graphics options are a little
bit different due to the OpenGL app already launched in
the existing user session. Actually, I'm surprised that it
works at all. I would have expected that the hardware
OpenGL app throws an error when remoting into the existing session.

I'm afraid that there's not much can do about this behaviour
if you don't want to invest into Citrix (HDX Pro) or VMware/Teradici
(PCoIP in HW) which supports 3D graphics acceleration in
hardware from workstation to workstation. Another option
is to run your OpenGL apps in Win7 virtual desktops hosted
on Windows Server 2008 R2 SP1 Hyper-V and use the
RemoteFX extension of the RDP protocol. This option also
supports OpenGL in hardware if the appropriate graphics
adapter is installed on the Hyper-V server.

Benny
~
latest workaround script
~

@echo off
echo.
echo Remote Desktop will be temporarily disconnected . . . please reconnect after a few seconds.
echo.
pause
@echo on
REM The active session has an arrow as the first character
setlocal EnableDelayedExpansion
FOR /F %%A in ('qwinsta') do (
set tempSessionName=%%A
if "!tempSessionName:~0,1!"==">" (
@echo on
tscon.exe !tempSessionName:~1! /v /dest:console
@echo off
)
)
@echo off
echo.
echo Starting MyProgram.exe . . .
@echo on
start MyProgram.exe
@echo off
echo.
pause
~~~

looks like Chrome solves this problem by using ANGLE:

https://opensource.google/projects/angle

"How Google uses ANGLE: ANGLE is used by Chromium and Google Chrome to enable WebGL functionality without having to rely on OpenGL drivers."

A simpler solution than ANGLE: the library https://github.com/gonutz/d3d9 offers DirectX bindings for Golang.

I confirmed they work by trying this client game (by the same author) and it ran fine over RDP on windows 2016 virtual machine: https://github.com/gonutz/ld36 (whereas ebiten always crashes on the same setup with the "panic: ui: glfw.CreateWindow must not return nil" at github.com/hajimehoshi/ebiten/internal/uidriver/glfw/ui.go:122

Apparently Allegro uses the directX when available too. https://github.com/dradtke/go-allegro

Windows virtual machines also might not support OpenGL/GLFW. Is there a way to force a different graphics driver, @hajimehoshi , or none at all?

I confirmed OpenGL (and Ebiten) worked on Parallels. I'm not sure the others.

A simpler solution than ANGLE: the library https://github.com/gonutz/d3d9 offers DirectX bindings for Golang.

Using Angle, or directly DirectX 10 sounds the way to go. (I'd want to avoid 9 since 9 can cause device lost)

I understand using DirectX in some forms is the way to go, but the cost is too large compared to the benefit: the benefit is only for remote desktops so far?

the benefit is only for remote desktops so far?

Yes.

I thought though, that there might be some way to avoid needing a driver at all...

If a driver is required, I agree it hardly seems worth making ebiten portable to remote windows.

Another benefit would be that we could test Ebiten on VMs easier (It looks like Ebiten on Windows didn't work well on TravisCI and GitHub Actions).

Yes, that and some 10-15% better performance. I think Vulkan is really the way to go here; I see that Godot is working on porting their stuff to Vulkan.

update: references:

https://godotengine.org/article/vulkan-progress-report-1

https://en.wikipedia.org/wiki/Vulkan_(API)

Although it may be a bit bleeding edge. ANGLE is probably the more sure thing, battled hardened by being used for chrome and firefox.

I'm not talking about Vulkan?

I'm not talking about Vulkan?

Is that a question?

No. I understand you suggested Vulkan instead of DirectX, but as Ebiten's graphics usage is very limited, I feel like using DirectX directly should be enough. Actually I've succeeded to port the graphics driver to Metal in Ebiten.

One very simple approach might be to use a translator like GLOVE

https://github.com/Think-Silicon/GLOVE

It takes in GL ES and writes out Vulkan. So possibly no re-programming required.

Again, as I said, I don't plan to use Vulkan on Windows :-)

https://github.com/Think-Silicon/GLOVE

Or MoltenVK? I know there are such translating layers, but as Ebiten's graphics usage is very limited, writing code that uses DirectX should not be so painful.

as Ebiten's graphics usage is very limited, writing code that uses DirectX should not be so painful.

Good to hear!

I get the same issue as above running in a Windows Virtual Machine.

I am an Ubuntu user though (so I don't really care about Windows). I was just curious to see if my Linux code worked on a Windows machine for the fun of it. I run Windows Virtualbox on Ubuntu and get this error (even for the examples):

PS C:\Users\colle\go\src\github.com\hajimehoshi\ebiten\examples\animation> go run .\main.go                                                         go: downloading golang.org/x/sys v0.0.0-20200812155832-6a926be9bd1d
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x558e72]

goroutine 1 [running, locked to thread]:
github.com/hajimehoshi/ebiten/internal/glfw.(*Window).MakeContextCurrent(0x0)
        C:/Users/colle/go/src/github.com/hajimehoshi/ebiten/internal/glfw/glfw_windows.go:175 +0x42
github.com/hajimehoshi/ebiten/internal/uidriver/glfw.(*UserInterface).createWindow(0x7a4460, 0xf, 0x0)
        C:/Users/colle/go/src/github.com/hajimehoshi/ebiten/internal/uidriver/glfw/ui.go:646 +0x1f8
github.com/hajimehoshi/ebiten/internal/uidriver/glfw.(*UserInterface).run.func1(0xc0000181e0, 0xc000075df0)
        C:/Users/colle/go/src/github.com/hajimehoshi/ebiten/internal/uidriver/glfw/ui.go:723 +0x19d
github.com/hajimehoshi/ebiten/internal/thread.(*Thread).Loop(0xc0000306d0)
        C:/Users/colle/go/src/github.com/hajimehoshi/ebiten/internal/thread/thread.go:45 +0x98
github.com/hajimehoshi/ebiten/internal/uidriver/glfw.(*UserInterface).Run(0x7a4460, 0x615cc0, 0x7a82e0, 0x0, 0x5a9220)
        C:/Users/colle/go/src/github.com/hajimehoshi/ebiten/internal/uidriver/glfw/ui.go:619 +0x160
github.com/hajimehoshi/ebiten.runGame(0x614a80, 0xc0000a4e10, 0x0, 0x9e8110, 0xc00000a710)
        C:/Users/colle/go/src/github.com/hajimehoshi/ebiten/run.go:323 +0x89
github.com/hajimehoshi/ebiten.RunGame(0x614b00, 0xc00000a710, 0x0, 0xc00003c140)
        C:/Users/colle/go/src/github.com/hajimehoshi/ebiten/run.go:314 +0xae
main.main()
        C:/Users/colle/go/src/github.com/hajimehoshi/ebiten/examples/animation/main.go:84 +0x191
exit status 2

Again I don't really care as I typically only use Ubuntu... just thought I would report the error.

Hi, thank you for reporting!

It looks like OpenGL doesn't work on Windows VM (I have already confirmed a similar fact on GitHub Workflow Windows VMs). The possible solution is, as we have already known, using DirectX instead of OpenGL.

Was this page helpful?
0 / 5 - 0 ratings