-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: patch for the main thread (awt | lwjgl3) #2935
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -340,16 +340,14 @@ public void removeNotify() { | |
| hasNativePeer.set(false); | ||
| reinitcontext.set(true); | ||
|
|
||
| while (reinitcontext.get()) { | ||
| while (reinitcontext.get() && parallel.get()) { | ||
| try { | ||
| lock.wait(); | ||
| } catch (InterruptedException ex) { | ||
| super.removeNotify(); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| reinitcontext.set(false); | ||
| } | ||
|
|
||
| // GL context is dead at this point | ||
|
|
@@ -411,6 +409,13 @@ public Graphics getGraphics() { | |
| /** Notify if there is a change in canvas dimensions. */ | ||
| private final AtomicBoolean needResize = new AtomicBoolean(false); | ||
|
|
||
| /** | ||
| * Flag indicating whether a custom thread is used to separate GL rendering | ||
| * from the EDT; its value is false if the main thread is used via the | ||
| * {@code SwingUtilities.invokeLater() } function. | ||
| */ | ||
| private final AtomicBoolean parallel = new AtomicBoolean(false); | ||
|
|
||
| /** | ||
| * Flag that uses the context to check if it is initialized or not, this prevents | ||
| * it from being initialized multiple times and potentially breaking the JVM. | ||
|
|
@@ -513,6 +518,7 @@ public boolean checkVisibilityState() { | |
| * Here the entire GL context is rendered and initialized. | ||
| */ | ||
| @Override | ||
| @SuppressWarnings("deprecation") | ||
| public void run() { | ||
| if (listener == null) { | ||
| throw new IllegalStateException( | ||
|
|
@@ -525,8 +531,8 @@ public void run() { | |
| while (true) { | ||
| if (needResize.getAndSet(false)) { | ||
| settings.setResolution(framebufferWidth, framebufferHeight); | ||
| listener.reshape(framebufferWidth, framebufferHeight, framebufferWidth, framebufferHeight); | ||
| listener.reshape(framebufferWidth, framebufferHeight); | ||
| listener.reshape(framebufferWidth, framebufferHeight, framebufferWidth, framebufferHeight); | ||
| } | ||
|
|
||
| synchronized (lock) { | ||
|
|
@@ -588,9 +594,6 @@ public void run() { | |
| } finally { | ||
| canvas.unlock(); | ||
| } | ||
|
|
||
| // Sync the display on some systems. | ||
| Toolkit.getDefaultToolkit().sync(); | ||
| } | ||
| } catch (Throwable ex) { | ||
| listener.handleError("Error while swapping buffers", ex); | ||
|
|
@@ -607,6 +610,17 @@ public void run() { | |
| if (needClose.get()) { | ||
| break; | ||
| } | ||
|
|
||
| if (! parallel.get()) { | ||
| // Sync the display on some systems. | ||
| Toolkit.getDefaultToolkit().sync(); | ||
| break; | ||
| } | ||
|
JNightRider marked this conversation as resolved.
|
||
| } | ||
|
|
||
| if (!parallel.get() && !needClose.get()) { | ||
| SwingUtilities.invokeLater(() -> run()); | ||
| return; | ||
| } | ||
|
|
||
| deinitInThread(); | ||
|
|
@@ -669,6 +683,12 @@ public void create(boolean waitFor) { | |
| if (this.contextFlag.get()) { | ||
| return; | ||
| } | ||
| /* | ||
| * Note that JME does not run on a thread parallel to the AWT EDT; | ||
| * this applies only to macOS. | ||
| */ | ||
| this.parallel.set(Platform.get() != Platform.MACOSX); | ||
|
|
||
| // create context | ||
| super.create(waitFor); | ||
| this.contextFlag.set(true); | ||
|
|
@@ -720,8 +740,8 @@ protected void createContext(AppSettings settings) { | |
|
|
||
| RENDER_CONFIGS.computeIfAbsent(settings.getRenderer(), (t) -> { | ||
| return (data) -> { | ||
| data.majorVersion = 2; | ||
| data.minorVersion = 0; | ||
| data.majorVersion = 3; | ||
| data.minorVersion = 2; | ||
|
Comment on lines
+743
to
+744
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fallback renderer configuration changed from GL 2.0 to GL 3.2 here. It is unrelated to the main-thread fix (it only triggers for renderer strings missing from
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even though it is a minor change that doesn't actually affect anything (since the minimum supported version is already set to that value) should I create a separate PR for it? |
||
| }; | ||
| }).accept(glData); | ||
|
|
||
|
|
@@ -759,9 +779,14 @@ protected void createContext(AppSettings settings) { | |
| glData.forwardCompatible = false; | ||
|
|
||
| allowSwapBuffers = settings.isSwapBuffers(); | ||
|
|
||
| canvas.createContext(); | ||
| canvas.makeCurrent(); | ||
|
|
||
| try { | ||
| canvas.lock(); | ||
| canvas.makeCurrent(); | ||
| } finally { | ||
| canvas.unlock(); | ||
| } | ||
|
|
||
| SwingUtilities.invokeLater(() -> { | ||
| canvas.validate(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This removes the call to
SystemListener.reshape(int, int). That overload is deprecated but explicitly "kept only for backward compatibility", andLwjglWindow.updateSizes()still invokes both overloads. After this change an AWT-canvas app whoseSystemListener/Applicationoverrides only the 2-arg method silently stops receiving resize notifications when the canvas is resized, while the same app on theDisplaypath still gets them. This is also outside the scope of the main-thread fix. Keep both calls unless the removal is deliberate and documented:Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I started working on this PR, the new
reshape()method called the old method (causing a duplicate call) but it seems this has been removed (in this PR #2881).Was there really any difference between having the new method call the old one and making the call explicitly whenever necessary?
working on the changes