mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 01:54:47 +02:00
8252133: The java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java fails if metal pipeline is active
Reviewed-by: prr
This commit is contained in:
parent
afc967fcd0
commit
e5870cf002
3 changed files with 84 additions and 56 deletions
|
@ -131,9 +131,14 @@ public final class CGraphicsDevice extends GraphicsDevice
|
||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidate(final int defaultDisplayID) {
|
/**
|
||||||
|
* Invalidates this device so it will point to some other "new" device.
|
||||||
|
*
|
||||||
|
* @param device the new device, usually the main screen
|
||||||
|
*/
|
||||||
|
public void invalidate(CGraphicsDevice device) {
|
||||||
//TODO do we need to restore the full-screen window/modes on old device?
|
//TODO do we need to restore the full-screen window/modes on old device?
|
||||||
displayID = defaultDisplayID;
|
displayID = device.displayID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
package sun.awt;
|
package sun.awt;
|
||||||
|
|
||||||
import java.awt.AWTError;
|
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.GraphicsConfiguration;
|
import java.awt.GraphicsConfiguration;
|
||||||
import java.awt.GraphicsDevice;
|
import java.awt.GraphicsDevice;
|
||||||
|
@ -112,7 +111,7 @@ public final class CGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Populate the device table */
|
/* Populate the device table */
|
||||||
initDevices();
|
rebuildDevices();
|
||||||
|
|
||||||
/* Register our display reconfiguration listener */
|
/* Register our display reconfiguration listener */
|
||||||
displayReconfigContext = registerDisplayReconfiguration();
|
displayReconfigContext = registerDisplayReconfiguration();
|
||||||
|
@ -121,33 +120,27 @@ public final class CGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the list of devices and notify listeners.
|
||||||
|
*/
|
||||||
|
private void rebuildDevices() {
|
||||||
|
initDevices();
|
||||||
|
displayChanged();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the CoreGraphics Display Reconfiguration Callback.
|
* Called by the CoreGraphics Display Reconfiguration Callback.
|
||||||
*
|
*
|
||||||
* @param displayId CoreGraphics displayId
|
* @param displayId CoreGraphics displayId
|
||||||
* @param removed true if displayId was removed, false otherwise.
|
* @param removed true if displayId was removed, false otherwise.
|
||||||
*/
|
*/
|
||||||
void _displayReconfiguration(final int displayId, final boolean removed) {
|
void _displayReconfiguration(int displayId, boolean removed) {
|
||||||
synchronized (this) {
|
// we ignore the passed parameters and check removed devices ourself
|
||||||
if (removed && devices.containsKey(displayId)) {
|
// Note that it is possible that this callback is called when the
|
||||||
final CGraphicsDevice gd = devices.remove(displayId);
|
// monitors are not added nor removed, but when the video card is
|
||||||
oldDevices.add(new WeakReference<>(gd));
|
// switched to/from the discrete video card, so we should try to map the
|
||||||
}
|
// old to the new devices.
|
||||||
}
|
rebuildDevices();
|
||||||
initDevices();
|
|
||||||
|
|
||||||
// Need to notify old devices, in case the user hold the reference to it
|
|
||||||
for (ListIterator<WeakReference<CGraphicsDevice>> it =
|
|
||||||
oldDevices.listIterator(); it.hasNext(); ) {
|
|
||||||
CGraphicsDevice gd = it.next().get();
|
|
||||||
if (gd != null) {
|
|
||||||
gd.invalidate(mainDisplayID);
|
|
||||||
gd.displayChanged();
|
|
||||||
} else {
|
|
||||||
// no more references to this device, remove it
|
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -163,44 +156,74 @@ public final class CGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||||
/**
|
/**
|
||||||
* (Re)create all CGraphicsDevices, reuses a devices if it is possible.
|
* (Re)create all CGraphicsDevices, reuses a devices if it is possible.
|
||||||
*/
|
*/
|
||||||
private void initDevices() {
|
private synchronized void initDevices() {
|
||||||
synchronized (this) {
|
Map<Integer, CGraphicsDevice> old = new HashMap<>(devices);
|
||||||
final Map<Integer, CGraphicsDevice> old = new HashMap<>(devices);
|
devices.clear();
|
||||||
devices.clear();
|
mainDisplayID = getMainDisplayID();
|
||||||
|
|
||||||
mainDisplayID = getMainDisplayID();
|
// initialization of the graphics device may change list of displays on
|
||||||
|
// hybrid systems via an activation of discrete video.
|
||||||
|
// So, we initialize the main display first, then retrieve actual list
|
||||||
|
// of displays, and then recheck the main display again.
|
||||||
|
if (!old.containsKey(mainDisplayID)) {
|
||||||
|
old.put(mainDisplayID, new CGraphicsDevice(mainDisplayID));
|
||||||
|
}
|
||||||
|
|
||||||
// initialization of the graphics device may change
|
int[] displayIDs = getDisplayIDs();
|
||||||
// list of displays on hybrid systems via an activation
|
if (displayIDs.length == 0) {
|
||||||
// of discrete video.
|
// we could throw AWTError in this case.
|
||||||
// So, we initialize the main display first, and then
|
displayIDs = new int[]{mainDisplayID};
|
||||||
// retrieve actual list of displays.
|
}
|
||||||
if (!old.containsKey(mainDisplayID)) {
|
for (int id : displayIDs) {
|
||||||
old.put(mainDisplayID, new CGraphicsDevice(mainDisplayID));
|
devices.put(id, old.containsKey(id) ? old.remove(id)
|
||||||
}
|
: new CGraphicsDevice(id));
|
||||||
|
}
|
||||||
|
// fetch the main display again, the old value might be outdated
|
||||||
|
mainDisplayID = getMainDisplayID();
|
||||||
|
|
||||||
for (final int id : getDisplayIDs()) {
|
// unlikely but make sure the main screen is in the list of screens,
|
||||||
devices.put(id, old.containsKey(id) ? old.get(id)
|
// most probably one more "displayReconfiguration" is on the road if not
|
||||||
: new CGraphicsDevice(id));
|
if (!devices.containsKey(mainDisplayID)) {
|
||||||
|
mainDisplayID = displayIDs[0]; // best we can do
|
||||||
|
}
|
||||||
|
// if a device was not reused it should be invalidated
|
||||||
|
for (CGraphicsDevice gd : old.values()) {
|
||||||
|
oldDevices.add(new WeakReference<>(gd));
|
||||||
|
}
|
||||||
|
// Need to notify old devices, in case the user hold the reference to it
|
||||||
|
for (ListIterator<WeakReference<CGraphicsDevice>> it =
|
||||||
|
oldDevices.listIterator(); it.hasNext(); ) {
|
||||||
|
CGraphicsDevice gd = it.next().get();
|
||||||
|
if (gd != null) {
|
||||||
|
// If the old device has the same bounds as some new device
|
||||||
|
// then map that old device to the new, or to the main screen.
|
||||||
|
CGraphicsDevice similarDevice = getSimilarDevice(gd);
|
||||||
|
if (similarDevice == null) {
|
||||||
|
gd.invalidate(devices.get(mainDisplayID));
|
||||||
|
} else {
|
||||||
|
gd.invalidate(similarDevice);
|
||||||
|
}
|
||||||
|
gd.displayChanged();
|
||||||
|
} else {
|
||||||
|
// no more references to this device, remove it
|
||||||
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
displayChanged();
|
}
|
||||||
|
|
||||||
|
private CGraphicsDevice getSimilarDevice(CGraphicsDevice old) {
|
||||||
|
for (CGraphicsDevice device : devices.values()) {
|
||||||
|
if (device.getBounds().equals(old.getBounds())) {
|
||||||
|
// for now we will use the bounds only
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
|
public synchronized GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
|
||||||
CGraphicsDevice d = devices.get(mainDisplayID);
|
return devices.get(mainDisplayID);
|
||||||
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);
|
|
||||||
if (d == null) {
|
|
||||||
throw new AWTError("no screen devices");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -41,7 +41,7 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 4836241 6364134 8232200
|
* @bug 4836241 6364134 8232200 8252133
|
||||||
* @key headful
|
* @key headful
|
||||||
* @summary verify that images are restored correctly after display mode
|
* @summary verify that images are restored correctly after display mode
|
||||||
* switches and that no other rendering or crash problems occur
|
* switches and that no other rendering or crash problems occur
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue