2d-dev is better and Sergey already forwarded it. -Phil.
> On Jan 10, 2017, at 2:03 PM, Rob McKenna <rob.mcke...@oracle.com> wrote: > > Hi Karl, thanks for the submission. I'm sending this to awt-dev and > bcc'ing jdk8u-dev as thats a more appropriate venue for this discussion. > > -Rob > >> On 11/01/17 08:44, Karl von Randow wrote: >> I have encountered a deadlock in Java 1.8.0_112 when changing between >> discrete and integrated GPU on a retina MacBook Pro. The deadlock is between: >> >> CGLGraphicsConfig.getCGLConfigInfo, running on AWT.EventQueue, trying to >> call [GraphicsConfigUtil _getCGLConfigInfo:] on >> the main thread (AppKit thread) while it holds the AWT lock and is >> synchronized on CGraphicsEnvironment. >> >> and >> >> A) the AppKit main thread trying to call >> CGraphicsEnvironment._displayReconfiguration (via displaycb_handle in >> CGraphicsEnv.m) >> and synchronizing on CGraphicsEnvironment—deadlock. >> >> or >> >> B) the AppKit main thread trying to render, and trying to acquire the >> OGLRenderQueue lock (which is the the AWT lock) >> >> >> SUPPORTING STACK DUMPS >> >> - SCENARIO A >> >> CGraphicsEnvironment._displayReconfiguration is called on the main thread >> since >> 8041900: [macosx] Java forces the use of discrete GPU >> (https://bugs.openjdk.java.net/browse/JDK-8041900 >> <https://bugs.openjdk.java.net/browse/JDK-8041900>) which appears as >> changeset 11227. >> In the native thread dump below you can see the frame for displaycb_handle >> which is the block dispatched to the main thread to call >> CGraphicsEnvironment._displayReconfiguration. >> >> Java stacks >> >> "AWT-EventQueue-0" #16 prio=6 os_prio=31 tid=0x00007fbc72a0a800 nid=0x1251f >> runnable [0x000070000e443000] >> java.lang.Thread.State: RUNNABLE >> at sun.java2d.opengl.CGLGraphicsConfig.getCGLConfigInfo(Native Method) >> at >> sun.java2d.opengl.CGLGraphicsConfig.getConfig(CGLGraphicsConfig.java:147) >> at sun.awt.CGraphicsDevice.<init>(CGraphicsDevice.java:64) >> at sun.awt.CGraphicsEnvironment.initDevices(CGraphicsEnvironment.java:163) >> - locked <0x00000006c0721bb0> (a sun.awt.CGraphicsEnvironment) >> at >> sun.awt.CGraphicsEnvironment.getDefaultScreenDevice(CGraphicsEnvironment.java:181) >> - locked <0x00000006c0721bb0> (a sun.awt.CGraphicsEnvironment) >> at sun.lwawt.macosx.LWCToolkit.getScreenResolution(LWCToolkit.java:415) >> at >> net.miginfocom.swing.SwingComponentWrapper.getHorizontalScreenDPI(SwingComponentWrapper.java:260) >> at >> net.miginfocom.swing.SwingComponentWrapper.getPixelUnitFactor(SwingComponentWrapper.java:119) >> [SNIP] >> at java.awt.Container.layout(Container.java:1510) >> at java.awt.Container.doLayout(Container.java:1499) >> at java.awt.Container.validateTree(Container.java:1695) >> [SNIP] >> at >> javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1750) >> [SNIP] >> at >> java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) >> at >> java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) >> at >> java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) >> at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) >> at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) >> at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) >> >> "AppKit Thread" #11 daemon prio=5 os_prio=31 tid=0x00007fbc75046800 >> nid=0x307 waiting for monitor entry [0x00007fff5b579000] >> java.lang.Thread.State: BLOCKED (on object monitor) >> at >> sun.awt.CGraphicsEnvironment._displayReconfiguration(CGraphicsEnvironment.java:129) >> - waiting to lock <0x00000006c0721bb0> (a sun.awt.CGraphicsEnvironment) >> >> Native stacks >> >> Thread 0x6828c3 DispatchQueue 1 Thread name "AppKit >> Thread" 1000 samples (1-1000) priority 46 (base >> 46) cpu time <0.001 >> 1000 start + 52 (Charles + 5156) [0x104682424] >> 1000 main + 153 (Charles + 5321) [0x1046824c9] >> 1000 launch + 10872 (Charles + 16520) [0x104685088] >> 1000 JLI_Launch + 1952 (libjli.dylib + 5668) [0x104702624] >> 1000 CreateExecutionEnvironment + 871 (libjli.dylib + 22781) >> [0x1047068fd] >> 1000 CFRunLoopRunSpecific + 420 (CoreFoundation + 555380) >> [0x7fff97665974] >> 1000 __CFRunLoopRun + 934 (CoreFoundation + 556918) >> [0x7fff97665f76] >> 1000 __CFRunLoopDoSources0 + 557 (CoreFoundation + 559741) >> [0x7fff97666a7d] >> 1000 >> __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 >> (CoreFoundation + 686465) [0x7fff97685981] >> 1000 __NSThreadPerformPerform + 326 (Foundation + >> 465034) [0x7fff990c988a] >> 1000 -[AWTStarter starter:] + 905 (libawt_lwawt.dylib >> + 286207) [0x113081dff] >> 1000 +[NSApplicationAWT runAWTLoopWithApp:] + 156 >> (libosxapp.dylib + 8525) [0x1130fa14d] >> [SNIP] >> 1000 +[JNFRunLoop >> _performCopiedBlock:] + 17 (JavaNativeFoundation + 28474) [0x112d0df3a] >> 1000 >> __displaycb_handle_block_invoke_1 + 172 (libawt_lwawt.dylib + 119659) >> [0x11305936b] >> 1000 >> JNFPerformEnvBlock + 87 (JavaNativeFoundation + 27229) [0x112d0da5d] >> 1000 >> __displaycb_handle_block_invoke_2 + 80 (libawt_lwawt.dylib + 119988) >> [0x1130594b4] >> 1000 >> JNFCallVoidMethod + 187 (JavaNativeFoundation + 13743) [0x112d0a5af] >> 1000 >> jni_CallVoidMethodV + 248 (libjvm.dylib + 3069241) [0x106301539] >> 1000 >> jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, >> _jmethodID*, JNI_ArgumentPusher*, Thread*) + 748 (libjvm.dylib + 3124227) >> [0x10630ec03] >> 1000 >> JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, >> Thread*) + 1710 (libjvm.dylib + 3015574) [0x1062f4396] >> 1000 ??? >> [0x113db94e7] >> 1000 ??? >> [0x113dde021] >> 1000 >> InterpreterRuntime::monitorenter(JavaThread*, BasicObjectLock*) + 165 >> (libjvm.dylib + 2995347) [0x1062ef493] >> 1000 >> ObjectMonitor::enter(Thread*) + 472 (libjvm.dylib + 4524724) [0x106464ab4] >> >> 1000 ObjectMonitor::EnterI(Thread*) + 532 (libjvm.dylib + 4521584) >> [0x106463e70] >> >> 1000 os::PlatformEvent::park(long) + 404 (libjvm.dylib + 4561328) >> [0x10646d9b0] >> >> 1000 __psynch_cvwait + 10 (libsystem_kernel.dylib + 105606) [0x7fffaccecc86] >> >> *1000 psynch_cvcontinue + 0 (pthread + 39138) [0xffffff7f80f978e2] >> >> Thread 0x68292c Thread name "Java: AWT-EventQueue-0" >> 1000 samples (1-1000) priority 31 (base 31) >> 1000 thread_start + 13 (libsystem_pthread.dylib + 12797) [0x7fffacdd51fd] >> 1000 _pthread_start + 286 (libsystem_pthread.dylib + 14839) >> [0x7fffacdd59f7] >> 1000 _pthread_body + 180 (libsystem_pthread.dylib + 15019) >> [0x7fffacdd5aab] >> 1000 java_start(Thread*) + 246 (libjvm.dylib + 4574506) [0x106470d2a] >> 1000 JavaThread::run() + 448 (libjvm.dylib + 5486408) [0x10654f748] >> 1000 JavaThread::thread_main_inner() + 155 (libjvm.dylib + >> 5480593) [0x10654e091] >> 1000 thread_entry(JavaThread*, Thread*) + 124 (libjvm.dylib + >> 3270354) [0x1063326d2] >> 1000 JavaCalls::call_virtual(JavaValue*, Handle, >> KlassHandle, Symbol*, Symbol*, Thread*) + 74 (libjvm.dylib + 3017936) >> [0x1062f4cd0] >> 1000 JavaCalls::call_virtual(JavaValue*, KlassHandle, >> Symbol*, Symbol*, JavaCallArguments*, Thread*) + 356 (libjvm.dylib + >> 3017508) [0x1062f4b24] >> 1000 JavaCalls::call_helper(JavaValue*, methodHandle*, >> JavaCallArguments*, Thread*) + 1710 (libjvm.dylib + 3015574) [0x1062f4396] >> [SNIP] >> >> 1000 >> Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo + 279 >> (libawt_lwawt.dylib + 107562) [0x11305642a] >> >> 1000 -[NSObject(NSThreadPerformAdditions) >> performSelectorOnMainThread:withObject:waitUntilDone:] + 131 (Foundation + >> 203394) [0x7fff99089a82] >> >> 1000 -[NSObject(NSThreadPerformAdditions) >> performSelector:onThread:withObject:waitUntilDone:modes:] + 904 (Foundation >> + 204424) [0x7fff99089e88] >> >> 1000 -[NSCondition wait] + 240 (Foundation + 208331) >> [0x7fff9908adcb] >> >> 1000 __psynch_cvwait + 10 (libsystem_kernel.dylib + >> 105606) [0x7fffaccecc86] >> >> *1000 psynch_cvcontinue + 0 (pthread + 39138) >> [0xffffff7f80f978e2] >> >> >> >> >> >> >> - Scenario B >> >> Java stacks >> >> "AWT-EventQueue-0" #15 prio=6 os_prio=31 tid=0x00007fba611d2000 nid=0x1260f >> runnable [0x0000700005365000] >> java.lang.Thread.State: RUNNABLE >> at sun.java2d.opengl.CGLGraphicsConfig.getCGLConfigInfo(Native Method) >> at >> sun.java2d.opengl.CGLGraphicsConfig.getConfig(CGLGraphicsConfig.java:147) >> at sun.awt.CGraphicsDevice.<init>(CGraphicsDevice.java:64) >> at sun.awt.CGraphicsEnvironment.initDevices(CGraphicsEnvironment.java:163) >> - locked <0x00000006c0df8c18> (a sun.awt.CGraphicsEnvironment) >> at >> sun.awt.CGraphicsEnvironment.getDefaultScreenDevice(CGraphicsEnvironment.java:181) >> - locked <0x00000006c0df8c18> (a sun.awt.CGraphicsEnvironment) >> at sun.lwawt.macosx.LWCToolkit.getScreenResolution(LWCToolkit.java:415) >> at >> net.miginfocom.swing.SwingComponentWrapper.getHorizontalScreenDPI(SwingComponentWrapper.java:260) >> at >> net.miginfocom.swing.SwingComponentWrapper.getPixelUnitFactor(SwingComponentWrapper.java:119) >> at net.miginfocom.layout.UnitValue.getPixelsExact(UnitValue.java:305) >> at net.miginfocom.layout.UnitValue.getPixels(UnitValue.java:281) >> [SNIP] >> at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) >> at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) >> at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) >> >> "AppKit Thread" #11 daemon prio=5 os_prio=31 tid=0x00007fba59869800 >> nid=0x307 waiting on condition [0x00007fff52ac2000] >> java.lang.Thread.State: WAITING (parking) >> at sun.misc.Unsafe.park(Native Method) >> - parking to wait for <0x00000006c053b688> (a >> java.util.concurrent.locks.ReentrantLock$NonfairSync) >> at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) >> at >> java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) >> at >> java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870) >> at >> java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199) >> at >> java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209) >> at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285) >> at sun.awt.SunToolkit.awtLock(SunToolkit.java:253) >> at sun.java2d.pipe.RenderQueue.lock(RenderQueue.java:112) >> at sun.java2d.opengl.CGLLayer.drawInCGLContext(CGLLayer.java:139) >> >> Native stacks >> >> Thread 0x6764ca DispatchQueue 1 Thread name "AppKit >> Thread" 1000 samples (1-1000) priority 46 (base >> 46) >> 1000 start + 52 (Charles + 5156) [0x10d139424] >> 1000 main + 153 (Charles + 5321) [0x10d1394c9] >> 1000 launch + 10872 (Charles + 16520) [0x10d13c088] >> 1000 JLI_Launch + 1952 (libjli.dylib + 5668) [0x10d1b9624] >> 1000 CreateExecutionEnvironment + 871 (libjli.dylib + 22781) >> [0x10d1bd8fd] >> 1000 CFRunLoopRunSpecific + 420 (CoreFoundation + 555380) >> [0x7fff97665974] >> 1000 __CFRunLoopRun + 934 (CoreFoundation + 556918) >> [0x7fff97665f76] >> 1000 __CFRunLoopDoSources0 + 557 (CoreFoundation + 559741) >> [0x7fff97666a7d] >> 1000 >> __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 >> (CoreFoundation + 686465) [0x7fff97685981] >> 1000 __NSThreadPerformPerform + 326 (Foundation + >> 465034) [0x7fff990c988a] >> 1000 -[AWTStarter starter:] + 905 (libawt_lwawt.dylib >> + 286207) [0x12abc3dff] >> 1000 +[NSApplicationAWT runAWTLoopWithApp:] + 156 >> (libosxapp.dylib + 8525) [0x12ac3c14d] >> [SNIP] >> 1000 >> CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, >> void*) + 108 (QuartzCore + 69522) [0x7fff9d393f92] >> 1000 >> CA::Transaction::commit() + 475 (QuartzCore + 67121) [0x7fff9d393631] >> 1000 >> CA::Context::commit_transaction(CA::Transaction*) + 280 (QuartzCore + >> 1153144) [0x7fff9d49c878] >> 1000 >> CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 35 (QuartzCore + >> 1196185) [0x7fff9d4a7099] >> 1000 >> CA::Layer::display_if_needed(CA::Transaction*) + 572 (QuartzCore + 1195886) >> [0x7fff9d4a6f6e] >> 1000 -[CAOpenGLLayer >> _display] + 351 (QuartzCore + 1117583) [0x7fff9d493d8f] >> 1000 >> CAOpenGLLayerDraw(CAOpenGLLayer*, double, CVTimeStamp const*, unsigned int) >> + 873 (QuartzCore + 1118737) [0x7fff9d494211] >> 1000 -[CGLLayer >> drawInCGLContext:pixelFormat:forLayerTime:displayTime:] + 287 >> (libawt_lwawt.dylib + 109022) [0x12ab989de] >> 1000 >> JNFCallVoidMethod + 187 (JavaNativeFoundation + 13743) [0x12a84f5af] >> 1000 >> jni_CallVoidMethodV + 248 (libjvm.dylib + 3069241) [0x10edb8539] >> 1000 >> jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, >> _jmethodID*, JNI_ArgumentPusher*, Thread*) + 748 (libjvm.dylib + 3124227) >> [0x10edc5c03] >> 1000 >> JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, >> Thread*) + 1710 (libjvm.dylib + 3015574) [0x10edab396] >> 1000 >> ??? [0x10ffa0854] >> 1000 >> ??? [0x11027642a] >> >> 1000 Unsafe_Park + 126 (libjvm.dylib + 5571927) [0x10f01b557] >> >> 1000 Parker::park(bool, long) + 495 (libjvm.dylib + 4560765) [0x10ef2477d] >> >> 1000 __psynch_cvwait + 10 (libsystem_kernel.dylib + 105606) [0x7fffaccecc86] >> >> *1000 psynch_cvcontinue + 0 (pthread + 39138) [0xffffff7f80f978e2] >> >> Thread 0x67652b Thread name "Java: AWT-EventQueue-0" >> 1000 samples (1-1000) priority 31 (base 31) >> 1000 thread_start + 13 (libsystem_pthread.dylib + 12797) [0x7fffacdd51fd] >> 1000 _pthread_start + 286 (libsystem_pthread.dylib + 14839) >> [0x7fffacdd59f7] >> 1000 _pthread_body + 180 (libsystem_pthread.dylib + 15019) >> [0x7fffacdd5aab] >> 1000 java_start(Thread*) + 246 (libjvm.dylib + 4574506) [0x10ef27d2a] >> 1000 JavaThread::run() + 448 (libjvm.dylib + 5486408) [0x10f006748] >> 1000 JavaThread::thread_main_inner() + 155 (libjvm.dylib + >> 5480593) [0x10f005091] >> 1000 thread_entry(JavaThread*, Thread*) + 124 (libjvm.dylib + >> 3270354) [0x10ede96d2] >> [SNIP] >> >> 1000 ??? [0x10f7a0734] >> >> 1000 >> Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo + 279 >> (libawt_lwawt.dylib + 107562) [0x12ab9842a] >> >> 1000 -[NSObject(NSThreadPerformAdditions) >> performSelectorOnMainThread:withObject:waitUntilDone:] + 131 (Foundation + >> 203394) [0x7fff99089a82] >> >> 1000 -[NSObject(NSThreadPerformAdditions) >> performSelector:onThread:withObject:waitUntilDone:modes:] + 904 (Foundation >> + 204424) [0x7fff99089e88] >> >> 1000 -[NSCondition wait] + 240 (Foundation + 208331) >> [0x7fff9908adcb] >> >> 1000 __psynch_cvwait + 10 (libsystem_kernel.dylib + >> 105606) [0x7fffaccecc86] >> >> *1000 psynch_cvcontinue + 0 (pthread + 39138) >> [0xffffff7f80f978e2] >> >> >> INTERPRETATION >> >> The deadlock is a race condition when macOS changes between the discrete and >> integrated GPU. >> >> When the GPU changes, the result of CGraphicsEnvironment.getMainDisplayID() >> changes immediately (There is a comment in CGraphicsEnvironment.m >> that notes that the display ID changes in this case, and I have verified >> this) to return the new displayID, while the devices map is only built once >> initDevices() is called. >> >> CGLGraphicsConfig.getCGLConfigInfo (which is called as a consequence of >> initDevices, as per stack traces) calls out and waits on the AppKit main >> thread. I think this is >> always dangerous due to the locks that the code calling it holds. I think we >> should avoid getCGLConfigInfo being called on anything but the AppKit main >> thread. I believe >> this was the intention of 8041900: [macosx] Java forces the use of discrete >> GPU (https://bugs.openjdk.java.net/browse/JDK-8041900 >> <https://bugs.openjdk.java.net/browse/JDK-8041900>). >> >> CGraphicsEnvironment.getDefaultScreenDevice() is called from AWT layout code >> (as per the stacks) and it calls CGraphicsEnvironment.getMainDisplayID() >> each time. >> If CGraphicsEnvironment.getDefaultScreenDevice() is called _after_ the GPU >> change, but _before_ CGraphicsEnvironment._displayReconfiguration() has been >> called, >> the CGraphicsDevice for the new display ID cannot be found in the devices >> Map, so initDevices() is called from >> CGraphicsEnvironment.getDefaultScreenDevice() >> on the AWT-EventQueue thread. >> >> There is a note in getDefaultScreenDevice() for this case: >> we do not expect that this may happen, the only response is to >> re-initialize the list of devices >> >> Calling initDevices() here results in a call to >> CGLGraphicsConfig.getCGLConfigInfo, which then calls >> [GraphicsConfigUtil _getCGLConfigInfo:] on the AppKit main thread and waits >> for the result. >> >> As the current thread (AWT Event queue) is holding the AWT lock, and is >> synchronized on CGraphicsEnvironment, the two deadlock >> conditions described above can occur. >> >> >> REPRODUCABILITY >> >> This happens quite regularly on my machine, and for my users. To reproduce >> it I have launched my app while the integrated GPU is active, then launched >> and quit an app that requires the discrete GPU. One to five repetitions are >> required to create the hanging condition. >> >> I believe the issue is triggered by my use of MigLayout, which results in >> the call to CGraphicsEnvironment as per this excerpt from the stack traces >> above: >> >> at >> sun.awt.CGraphicsEnvironment.getDefaultScreenDevice(CGraphicsEnvironment.java:181) >> - locked <0x00000006c0721bb0> (a sun.awt.CGraphicsEnvironment) >> at sun.lwawt.macosx.LWCToolkit.getScreenResolution(LWCToolkit.java:415) >> at >> net.miginfocom.swing.SwingComponentWrapper.getHorizontalScreenDPI(SwingComponentWrapper.java:260) >> at >> net.miginfocom.swing.SwingComponentWrapper.getPixelUnitFactor(SwingComponentWrapper.java:119) >> >> >> PATCH >> >> I believe the solution is to remember the main display ID along with the >> devices Map, and to change the main display ID when initDevices is called. >> This appears to work in my setup. There is however _sometimes_ a flash of >> half-size rendering, presumably while the rendering is working on the old >> device >> before the reconfiguration / initDevices occurs. >> >> Below is a simple patch to demonstrate that approach. Generally I don’t >> think initDevices() should ever be called on the AWT-EventQueue, but in my >> tests (as per the comment) >> that no longer happens with this patch. >> >> diff -r 5dd7e4bae5c2 src/macosx/classes/sun/awt/CGraphicsEnvironment.java >> --- a/src/macosx/classes/sun/awt/CGraphicsEnvironment.java Thu Sep 22 >> 13:17:42 2016 -0700 >> +++ b/src/macosx/classes/sun/awt/CGraphicsEnvironment.java Sat Jan 07 >> 20:49:39 2017 +1300 >> @@ -95,6 +95,7 @@ >> >> /** Available CoreGraphics displays. */ >> private final Map<Integer, CGraphicsDevice> devices = new HashMap<>(5); >> + private int inittedMainDisplayID; >> >> /** Reference to the display reconfiguration callback context. */ >> private final long displayReconfigContext; >> @@ -153,6 +154,7 @@ >> devices.clear(); >> >> int mainID = getMainDisplayID(); >> + inittedMainDisplayID = mainID; >> >> // initialization of the graphics device may change >> // list of displays on hybrid systems via an activation >> @@ -173,14 +175,13 @@ >> >> @Override >> public synchronized GraphicsDevice getDefaultScreenDevice() throws >> HeadlessException { >> - final int mainDisplayID = getMainDisplayID(); >> - CGraphicsDevice d = devices.get(mainDisplayID); >> + CGraphicsDevice d = devices.get(inittedMainDisplayID); >> if (d == null) { >> // we do not expect that this may happen, the only response >> // is to re-initialize the list of devices >> initDevices(); >> >> - d = devices.get(mainDisplayID); >> + d = devices.get(inittedMainDisplayID); >> if (d == null) { >> throw new AWTError("no screen devices"); >> } >> >> >> >>