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

GLFW v3.4 #400

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

GLFW v3.4 #400

wants to merge 8 commits into from

Conversation

Geo25rey
Copy link

@Geo25rey Geo25rey commented May 5, 2024

Overview

This is a rough implementation of go-glfw using GLFW v3.4. I have done some basic testing on Linux Wayland and XWayland. I highly recommend reviewing by commit considering the nature and size of this PR.

I am also looking for people to test the builds and functionality on the various platforms listed below. I can personally continue testing on Linux and if I have extra time, MacOS Arm.

Closes: #393
Potentially fixes: #272 @dmitshur
Requesting Review from: @Jacalz

Rundown by commit

Testing

Preamble

I used the short Custom Cursor program for testing. It would probably be a good idea to test with other programs, as well. Does anyone have such test programs?

It is especially important to get more test programs for Wayland since more features than just setting the window icon are not supported by GLFW and/or the Wayland protocols yet, and I'm not sure of other implications of the SIGABRT behavior previously mentioned. For example, I could dynamically add some element to my window at runtime, which could crash my program with a cryptic abort message with no other context. At best, developers using go-glfw can report it here, and at worst a subset of users will report the issue to downstream projects that use go-glfw and the downstream developers may not know what to do with the error message.

cd v3.4/glfw; go run testdata/customcursor/main.go

  • Linux
    • Wayland
      • OpenGL (-tags linux,wayland)
      • GLESv1 (-tags linux,wayland,gles1)
        • doesn't compile on Arch Linux with latest Mesa drivers
      • GLESv2 (-tags linux,wayland,gles2)
      • GLESv3 (-tags linux,wayland,gles3)
        • doesn't compile on Arch Linux with latest Mesa drivers
      • Vulkan (-tags linux,wayland,vulkan)
    • X11
      • OpenGL (-tags linux)
      • GLESv1 (-tags linux,gles1)
        • doesn't compile on Arch Linux with latest Mesa drivers
      • GLESv2 (-tags linux,gles2)
      • GLESv3 (-tags linux,gles3)
        • doesn't compile on Arch Linux with latest Mesa drivers
      • Vulkan (-tags linux,vulkan)
  • BSD
    • FreeBSD
      • Wayland (-tags freebsd,wayland)
      • X11 (-tags freebsd)
    • NetBSD
      • Wayland (-tags netbsd,wayland)
      • X11 (-tags netbsd)
    • OpenBSD
      • Wayland (Is this unsupported? There is no tag set for this.)
      • X11 (-tags openbsd)
  • Mac
    • Arm (I can get to this at some point, but if someone would like to get to first, feel free. I'm not sure when I'll have time for it)
      • opengl32 (-tags darwin)
      • GLESv2 (-tags darwin,gles2)
    • x86
      • opengl32 (-tags darwin)
      • GLESv2 (-tags darwin,gles2)
  • Windows (not sure if both 10 & 11 need to be tested but better safe than sorry, right?)
    • 10
      • opengl32 (-tags windows)
      • GLESv2 (-tags windows,gles2)
    • 11
      • opengl32 (-tags windows)
      • GLESv2 (-tags windows,gles2)

@dmitshur
Copy link
Member

dmitshur commented May 6, 2024

Thanks for working on this.

I used the short Custom Cursor program for testing. It would probably be a good idea to test with other programs, as well. Does anyone have such test programs?

It's not much, but there are two small example programs in https://github.com/go-gl/example.


Out of the box, it fails to link on GOOS=darwin GOARCH=arm64 with:

# command-line-arguments
/usr/local/go/pkg/tool/darwin_arm64/link: running clang failed: exit status 1
Undefined symbols for architecture arm64:
  "__glfwPlatformFreeModule", referenced from:
      __glfwTerminateNull in 000002.o
      __glfwTerminateOSMesa in 000002.o
      _terminate in 000002.o
      __glfwInitVulkan in 000002.o
      __glfwTerminateVulkan in 000002.o
      __glfwInitOSMesa in 000002.o
      __glfwTerminateCocoa in 000003.o
      ...
  "__glfwPlatformGetModuleSymbol", referenced from:
      __glfwInitVulkan in 000002.o
      _glfwGetInstanceProcAddress in 000002.o
      __glfwInitOSMesa in 000002.o
      __glfwInitOSMesa in 000002.o
      __glfwInitOSMesa in 000002.o
      __glfwInitOSMesa in 000002.o
      __glfwInitOSMesa in 000002.o
      __glfwInitOSMesa in 000002.o
      __glfwInitOSMesa in 000002.o
      ...
  "__glfwPlatformLoadModule", referenced from:
      __glfwInitVulkan in 000002.o
      __glfwInitOSMesa in 000002.o
      __glfwLoadLocalVulkanLoaderCocoa in 000003.o
      __glfwInitEGL in 000003.o
      __glfwCreateContextEGL in 000003.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

That doesn't happen if this line is added to c_glfw_darwin.go:

 #include "glfw/src/cocoa_time.c"
+#include "glfw/src/posix_module.c"
 #include "glfw/src/posix_thread.c"

And with that at least basic functionality seems to work okay on macOS.

@Geo25rey
Copy link
Author

Geo25rey commented May 6, 2024

It's not much, but there are two small example programs in https://github.com/go-gl/example.

I'll go ahead and try these then.

c_glfw_darwin.go:

 #include "glfw/src/cocoa_time.c"
+#include "glfw/src/posix_module.c"
 #include "glfw/src/posix_thread.c"

Cool I'll add this in.

By the way, does this fix #272 for you? I think the upstream fix is included in GLFW v3.4.

@Geo25rey
Copy link
Author

Geo25rey commented May 6, 2024

Forgot to mention, @dmitshur can you test with -tags darwin,gles2 as well?

@Jacalz
Copy link
Collaborator

Jacalz commented May 6, 2024

Without the changes in #399 (and also defining _GNU_SOURCE for X11 compared to v3.3), I can't compile this on Fedora 40 due to implicit declarations now being treated as errors. Test results after that change:

I can replicate the same gles1 and gles3 failures on Fedora 40 (Wayland and X11) but I get the same error on v3.3 so that's fine? Compiling with -tags gles does work though.

Isn't Glfw v3.4 supposed to be able to switch between Wayland and X11 at runtime? If that is the case, should we enable that by default? Maybe have x11 and wayland tags for when you only want a single backend?

@Jacalz
Copy link
Collaborator

Jacalz commented May 6, 2024

FreeBSD X11 seems to get this error:
image

@Geo25rey
Copy link
Author

Geo25rey commented May 6, 2024

FreeBSD X11 seems to get this error: image

Does go build -tags freebsd work?

@Geo25rey
Copy link
Author

Geo25rey commented May 6, 2024

Without the changes in #399 (and also defining _GNU_SOURCE for X11 compared to v3.3), I can't compile this on Fedora 40 due to implicit declarations now being treated as errors. Test results after that change:

I can define _GNU_SOURCE, but I get this warning, which could be an error in Fedora?

In file included from ./c_glfw_lin.go:9:
./glfw/src/wl_window.c:27: warning: "_GNU_SOURCE" redefined
   27 | #define _GNU_SOURCE

I can replicate the same gles1 and gles3 failures on Fedora 40 (Wayland and X11) but I get the same error on v3.3 so that's fine? Compiling with -tags gles does work though.

I think it's fine too. To my understanding, GLES v1 & v3 are just different implementations of the OpenGL spec. So, it's probably good keeping them in, but they might be hard to test on bleeding edge distros like Arch and Fedora.

Also, I believe -tags gles is ignored when building for Linux & BSD. It would just choose the default which is -lGL implementation, right?

Isn't Glfw v3.4 supposed to be able to switch between Wayland and X11 at runtime? If that is the case, should we enable that by default? Maybe have x11 and wayland tags for when you only want a single backend?

I think it's best to keep X11 as the default to make the transition easier from v3.3 to v3.4, but if GLFW can now choose Wayland or X11 at runtime, maybe we can add support for this when both x11 and wayland tags are included.

@Geo25rey
Copy link
Author

Geo25rey commented May 6, 2024

I just pushed support for applying both X11 & Wayland on Linux with (-tags x11,wayland). I will add to BSD later, but I want to get the build working standalone on BSD first.

@Jacalz
Copy link
Collaborator

Jacalz commented May 6, 2024

Does go build -tags freebsd work?

That won't make any difference as I was building on FreeBSD. The GOOS value for the native operating system is always added automatically and the same goes for GOARCH. If you build your app on Linux for example, you don't need to pass -tags linux.

@Jacalz
Copy link
Collaborator

Jacalz commented May 6, 2024

I can define _GNU_SOURCE, but I get this warning, which could be an error in Fedora?

No, it is not an error in Fedora. It is a drawback of the solution. See #359, we need a better solution but right now that is better than not being able to compile. Implicit declarations are emitted (which is treated as an error on Fedora 40 due to stricter security settings) if your don't force _GNU_SOURCE to on but if you do, you get a warning that it is defined twice.

I think it's best to keep X11 as the default to make the transition easier from v3.3 to v3.4, but if GLFW can now choose Wayland or X11 at runtime, maybe we can add support for this when both x11 and wayland tags are included.

I'm not personally of doing that approach. Wayland is the future and I think we should enable the runtime switching support if we can. However, it is up to @dmitshur at the end of the day.

@metal3d
Copy link
Contributor

metal3d commented May 7, 2024

I can define _GNU_SOURCE, but I get this warning, which could be an error in Fedora?

In file included from ./c_glfw_lin.go:9:
./glfw/src/wl_window.c:27: warning: "_GNU_SOURCE" redefined
   27 | #define _GNU_SOURCE

Yes, this is a warning due to the manual definition inside GLFW source code. I don't understand why it's defined without a #ifndef - it could be a mistake or a wanted behavior.

// GLFW Options:
#cgo linux,!wayland CFLAGS: -D_GLFW_X11
#cgo linux,x11 CFLAGS: -D_GLFW_X11
#cgo linux,wayland CFLAGS: -D_GLFW_WAYLAND
Copy link
Contributor

@metal3d metal3d May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment on top, is it OK that _GNU_SOURCE is now globally set?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't want it set but I couldn't compile at all without it.

package glfw

/*
#cgo CFLAGS: -Iglfw/include -D_GNU_SOURCE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So then, _GNU_SOURCE is now globally set?

@Geo25rey
Copy link
Author

Geo25rey commented May 7, 2024

@metal3d I think _GNU_SOURCE is better to be set for all platforms since GLFW already handles cross-platform functionality. Ideally, _GNU_SOURCE should be set directly before the required #include, but it seems that there is an issue with the order the C source files are included into Go code. I think this is the most robust solution rather than hoping someone doesn't reorder the C source files in the future.

@Geo25rey
Copy link
Author

Geo25rey commented May 7, 2024

Wayland is the future

@Jacalz I completely agree, but this isn't about ideologies. This is about what is best for the users of this library.

we should enable the runtime switching support if we can.

I have added support for this on Linux like I said previously (-tags x11,wayland). Right now, I just have it setup as an opt-in feature rather than replacing the X11 default.

@Jacalz
Copy link
Collaborator

Jacalz commented May 7, 2024

@Jacalz I completely agree, but this isn't about ideologies. This is about what is best for the users of this library.

My point has nothing to do with ideologies. You are taking things out of context and I don't agree that being X11-only would be helpful in the long run. Enabling Wayland-only by default would be stupid but supporting dynamic switching between the two is a good compromise that we should try to make use of now that we can.

Enabling runtime switching by default is the best path forward given how quickly Wayland is getting adopted and some distros like Fedora are even disabling Xorg support (XWayland works yes, but you see the direction we are heading). Making the switch to enable Wayland support by default now is going to be the better option as a future-proof setting and that switch will be much harder to make down the line. Remember that v3.4 is an entirely new module import and it would be problematic to suddenly enable Wayland support and require an extra dependency when compiling later in the lifecycle of that existing in the repository. If we are to stay up to date with the times, that support needs to be enabled from the start. If you still want to have X11-only, I see no reason why people can't still use v3.3 given that it still will be maintained some time forward.

We have seen in Fyne that the community cares very much for Wayland support to be enabled and Flathub even marks an X11-only application as unsafe nowadays (https://flathub.org/apps/io.github.jacalz.rymdport). Having dynamic runtime switching gets us both X11 and Wayland support and a lot more people will actually use it instead of having to enable an obscure build tag combination.

@J7mbo
Copy link

J7mbo commented May 18, 2024

Hey @Geo25rey, given that Mac --> opengl32 is checked here, I tried building on an M3 with:

go build -tags darwin

And then running ./customcursor.

I had to comment out:

window.SetIcon([]image.Image{whiteTriangle})

in v3.4/glfw/testdata/customcursor/main.go:36, as it was complaining about Cocoa:

go-gl/glfw: internal error: an invalid error was not accepted by the caller: ErrorCode(65548): Cocoa: Regular windows do not have icons on macOS
go-gl/glfw: Please report this in the Go package issue tracker.
panic: ErrorCode(65548): Cocoa: Regular windows do not have icons on macOS

Given the above being commented out, the mouse passthrough I was looking for worked (with floating), after adding the Hint to window.go, so thanks a lot for that! :)

@Geo25rey
Copy link
Author

@J7mbo Thx for testing this out according to LWJGL/lwjgl3#695, this commit glfw/glfw@9a87c2a introduced 2 new errors affecting macOS and Wayland, so I think we should pass both GLFW_FEATURE_UNAVAILABLE and GLFW_FEATURE_UNIMPLEMENTED back as go errors instead of panicking

@Geo25rey
Copy link
Author

@J7mbo I just looked at your issue #375 (comment) and it looks like all the hints are out of date or have out of date descriptions so I will add them from here https://www.glfw.org/docs/3.4/window_guide.html#window_hints_wnd

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