Skip to content

Commit 6d73b25

Browse files
committed
JRE-359 CGraphicsEnvironment.getDefaultScreenDevice() returns null
Moved CG api calls to AppKit thread (cherry picked from commit fd0210f035199e8612097a2c1d42b90cfd2111f8) (cherry picked from commit 5e99e376d9dfe477401121878704630c3c13f9f7)
1 parent 5d98c94 commit 6d73b25

File tree

1 file changed

+50
-12
lines changed

1 file changed

+50
-12
lines changed

src/java.desktop/macosx/classes/sun/awt/CGraphicsEnvironment.java

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727

2828
import java.awt.*;
2929
import java.util.*;
30+
import java.util.concurrent.Callable;
3031

3132
import sun.java2d.*;
33+
import sun.lwawt.macosx.CThreading;
3234

3335
/**
3436
* This is an implementation of a GraphicsEnvironment object for the default
@@ -112,15 +114,18 @@ public CGraphicsEnvironment() {
112114
* @param displayId CoreGraphics displayId
113115
* @param removed true if displayId was removed, false otherwise.
114116
*/
117+
@SuppressWarnings("unused")
115118
void _displayReconfiguration(final int displayId, final boolean removed) {
116119
synchronized (this) {
120+
// We don't need to switch to AppKit, we're already there
121+
mainDisplayID = getMainDisplayID();
117122
if (removed && devices.containsKey(displayId)) {
118123
final CGraphicsDevice gd = devices.remove(displayId);
119-
gd.invalidate(getMainDisplayID());
124+
gd.invalidate(mainDisplayID);
120125
gd.displayChanged();
121126
}
122127
}
123-
initDevices();
128+
initDevices(mainDisplayID);
124129
}
125130

126131
@Override
@@ -136,30 +141,63 @@ protected void finalize() throws Throwable {
136141
/**
137142
* (Re)create all CGraphicsDevices, reuses a devices if it is possible.
138143
*/
139-
private void initDevices() {
144+
private void initDevices(int mainDisplID) {
140145
synchronized (this) {
141-
final Map<Integer, CGraphicsDevice> old = new HashMap<>(devices);
142-
devices.clear();
146+
mainDisplayID = mainDisplID;
147+
createDevices();
148+
}
149+
displayChanged();
150+
}
143151

144-
mainDisplayID = getMainDisplayID();
152+
private void initDevices() {
153+
synchronized (this) {
145154

146155
// initialization of the graphics device may change
147156
// list of displays on hybrid systems via an activation
148157
// of discrete video.
149158
// So, we initialize the main display first, and then
150159
// retrieve actual list of displays.
151-
if (!old.containsKey(mainDisplayID)) {
152-
old.put(mainDisplayID, new CGraphicsDevice(mainDisplayID));
153-
}
154160

155-
for (final int id : getDisplayIDs()) {
156-
devices.put(id, old.containsKey(id) ? old.get(id)
157-
: new CGraphicsDevice(id));
161+
try {
162+
mainDisplayID = CThreading.privilegedExecuteOnAppKit(
163+
CGraphicsEnvironment::getMainDisplayID);
164+
} catch (RuntimeException e) {
165+
throw e;
166+
} catch (Exception e) {
167+
throw new RuntimeException("Could not get main display ID: " +
168+
e.getMessage() );
158169
}
170+
171+
createDevices();
172+
159173
}
160174
displayChanged();
161175
}
162176

177+
private void createDevices() {
178+
final Map<Integer, CGraphicsDevice> old = new HashMap<>(devices);
179+
devices.clear();
180+
181+
if (!old.containsKey(mainDisplayID)) {
182+
old.put(mainDisplayID, new CGraphicsDevice(mainDisplayID));
183+
}
184+
int[] displayIDs;
185+
try {
186+
displayIDs = CThreading.privilegedExecuteOnAppKit(
187+
CGraphicsEnvironment::getDisplayIDs);
188+
} catch (RuntimeException e) {
189+
throw e;
190+
} catch (Exception e) {
191+
throw new RuntimeException("Could not get display IDs: " +
192+
e.getMessage());
193+
}
194+
195+
for (final int id : displayIDs) {
196+
devices.put(id, old.containsKey(id) ? old.get(id)
197+
: new CGraphicsDevice(id));
198+
}
199+
}
200+
163201
@Override
164202
public synchronized GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
165203
CGraphicsDevice d = devices.get(mainDisplayID);

0 commit comments

Comments
 (0)