@@ -340,16 +340,14 @@ public void removeNotify() {
340340 hasNativePeer .set (false );
341341 reinitcontext .set (true );
342342
343- while (reinitcontext .get ()) {
343+ while (reinitcontext . get () && parallel .get ()) {
344344 try {
345345 lock .wait ();
346346 } catch (InterruptedException ex ) {
347347 super .removeNotify ();
348348 return ;
349349 }
350350 }
351-
352- reinitcontext .set (false );
353351 }
354352
355353 // GL context is dead at this point
@@ -411,6 +409,13 @@ public Graphics getGraphics() {
411409 /** Notify if there is a change in canvas dimensions. */
412410 private final AtomicBoolean needResize = new AtomicBoolean (false );
413411
412+ /**
413+ * Flag indicating whether a custom thread is used to separate GL rendering
414+ * from the EDT; its value is false if the main thread is used via the
415+ * {@code SwingUtilities.invokeLater() } function.
416+ */
417+ private final AtomicBoolean parallel = new AtomicBoolean (false );
418+
414419 /**
415420 * Flag that uses the context to check if it is initialized or not, this prevents
416421 * it from being initialized multiple times and potentially breaking the JVM.
@@ -526,7 +531,6 @@ public void run() {
526531 if (needResize .getAndSet (false )) {
527532 settings .setResolution (framebufferWidth , framebufferHeight );
528533 listener .reshape (framebufferWidth , framebufferHeight , framebufferWidth , framebufferHeight );
529- listener .reshape (framebufferWidth , framebufferHeight );
530534 }
531535
532536 synchronized (lock ) {
@@ -588,9 +592,6 @@ public void run() {
588592 } finally {
589593 canvas .unlock ();
590594 }
591-
592- // Sync the display on some systems.
593- Toolkit .getDefaultToolkit ().sync ();
594595 }
595596 } catch (Throwable ex ) {
596597 listener .handleError ("Error while swapping buffers" , ex );
@@ -607,6 +608,17 @@ public void run() {
607608 if (needClose .get ()) {
608609 break ;
609610 }
611+
612+ if (! parallel .get ()) {
613+ // Sync the display on some systems.
614+ Toolkit .getDefaultToolkit ().sync ();
615+ break ;
616+ }
617+ }
618+
619+ if (!parallel .get () && !needClose .get ()) {
620+ SwingUtilities .invokeLater (() -> run ());
621+ return ;
610622 }
611623
612624 deinitInThread ();
@@ -669,6 +681,12 @@ public void create(boolean waitFor) {
669681 if (this .contextFlag .get ()) {
670682 return ;
671683 }
684+ /*
685+ * Note that JME does not run on a thread parallel to the AWT EDT;
686+ * this applies only to macOS.
687+ */
688+ this .parallel .set (Platform .get () != Platform .MACOSX );
689+
672690 // create context
673691 super .create (waitFor );
674692 this .contextFlag .set (true );
@@ -720,8 +738,8 @@ protected void createContext(AppSettings settings) {
720738
721739 RENDER_CONFIGS .computeIfAbsent (settings .getRenderer (), (t ) -> {
722740 return (data ) -> {
723- data .majorVersion = 2 ;
724- data .minorVersion = 0 ;
741+ data .majorVersion = 3 ;
742+ data .minorVersion = 2 ;
725743 };
726744 }).accept (glData );
727745
@@ -759,9 +777,14 @@ protected void createContext(AppSettings settings) {
759777 glData .forwardCompatible = false ;
760778
761779 allowSwapBuffers = settings .isSwapBuffers ();
762-
763780 canvas .createContext ();
764- canvas .makeCurrent ();
781+
782+ try {
783+ canvas .lock ();
784+ canvas .makeCurrent ();
785+ } finally {
786+ canvas .unlock ();
787+ }
765788
766789 SwingUtilities .invokeLater (() -> {
767790 canvas .validate ();
0 commit comments