From 293c5712ace2ee9b4b52c9ea01cc396803214cd9 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Sun, 23 Nov 2025 22:44:58 +1030 Subject: [PATCH] JDK-8210547 synchronise with OpenGL after the last window is presented --- .../java/com/sun/javafx/tk/quantum/GlassScene.java | 9 +++++++++ .../com/sun/javafx/tk/quantum/PaintCollector.java | 4 ++++ .../sun/javafx/tk/quantum/PresentingPainter.java | 2 +- .../src/main/java/com/sun/prism/Presentable.java | 4 ++++ .../main/java/com/sun/prism/es2/ES2SwapChain.java | 13 +++++++++++-- 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/GlassScene.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/GlassScene.java index ed5cc2a2f9b..e201fe704ae 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/GlassScene.java +++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/GlassScene.java @@ -65,6 +65,7 @@ abstract class GlassScene implements TKScene { private volatile boolean entireSceneDirty = true; private boolean doPresent = true; + private boolean doVSync = false; private final AtomicBoolean painting = new AtomicBoolean(false); private final boolean depthBuffer; @@ -307,6 +308,14 @@ public final synchronized boolean getDoPresent() { return doPresent; } + public final synchronized void setDoVSync(boolean value) { + doVSync = value; + } + + public final synchronized boolean getDoVsync() { + return doVSync; + } + protected Color getClearColor() { WindowStage windowStage = stage instanceof WindowStage ? (WindowStage)stage : null; if (windowStage != null && windowStage.getPlatformWindow() != null && diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/PaintCollector.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/PaintCollector.java index e6c538bc5d4..991e5e828e3 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/PaintCollector.java +++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/PaintCollector.java @@ -434,10 +434,14 @@ final void renderAll() { if (!needsHint) { needsHint = gs.isSynchronous(); } + } + + for (final GlassScene gs : dirtyScenes) { // On platforms with a window manager, we always set doPresent = true, because // we always need to rerender the scene if it's in the dirty list and we do a // swap on a per-window basis gs.setDoPresent(true); + gs.setDoVSync(needsHint && dirtyScenes.getLast() == gs); try { gs.repaint(); } catch (Throwable t) { diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java index c2895de7bcc..94e16183437 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java +++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java @@ -104,7 +104,7 @@ final class PresentingPainter extends ViewPainter { /* present for vsync buffer swap */ if (vs.getDoPresent()) { - if (!presentable.present()) { + if (!presentable.present(vs.getDoVsync())) { disposePresentable(); sceneState.getScene().entireSceneNeedsRepaint(); } diff --git a/modules/javafx.graphics/src/main/java/com/sun/prism/Presentable.java b/modules/javafx.graphics/src/main/java/com/sun/prism/Presentable.java index 8fc4c29016c..75367a4d745 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/prism/Presentable.java +++ b/modules/javafx.graphics/src/main/java/com/sun/prism/Presentable.java @@ -57,6 +57,10 @@ public interface Presentable extends RenderTarget { */ public boolean present(); + public default boolean present(boolean vsync) { + return present(); + } + public float getPixelScaleFactorX(); public float getPixelScaleFactorY(); } diff --git a/modules/javafx.graphics/src/main/java/com/sun/prism/es2/ES2SwapChain.java b/modules/javafx.graphics/src/main/java/com/sun/prism/es2/ES2SwapChain.java index b7b074d72bb..de49c50c6f8 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/prism/es2/ES2SwapChain.java +++ b/modules/javafx.graphics/src/main/java/com/sun/prism/es2/ES2SwapChain.java @@ -183,8 +183,16 @@ private void drawTexture(ES2Graphics g, RTTexture src, @Override public boolean present() { - boolean presented = drawable.swapBuffers(context.getGLContext()); - context.makeCurrent(null); + return drawable.swapBuffers(context.getGLContext()); + } + + @Override + public boolean present(boolean vsync) { + boolean presented = present(); + + if (vsync) + context.getGLContext().finish(); + return presented; } @@ -308,6 +316,7 @@ public void dispose() { } if (drawable != null) { + context.makeCurrent(null); drawable.dispose(); drawable = null; }