Skip to content
Permalink
Browse files
8252133: The java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java f…
…ails if metal pipeline is active

Reviewed-by: prr
  • Loading branch information
mrserb committed Oct 21, 2020
1 parent afc967f commit e5870cf0022f11328e9069a5f62ee60990243f36
@@ -131,9 +131,14 @@ public int getScaleFactor() {
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?
displayID = defaultDisplayID;
displayID = device.displayID;
}

@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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@

package sun.awt;

import java.awt.AWTError;
import java.awt.Font;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
@@ -112,7 +111,7 @@ public CGraphicsEnvironment() {
}

/* Populate the device table */
initDevices();
rebuildDevices();

/* Register our display reconfiguration listener */
displayReconfigContext = registerDisplayReconfiguration();
@@ -121,33 +120,27 @@ public CGraphicsEnvironment() {
}
}

/**
* Updates the list of devices and notify listeners.
*/
private void rebuildDevices() {
initDevices();
displayChanged();
}

/**
* Called by the CoreGraphics Display Reconfiguration Callback.
*
* @param displayId CoreGraphics displayId
* @param removed true if displayId was removed, false otherwise.
*/
void _displayReconfiguration(final int displayId, final boolean removed) {
synchronized (this) {
if (removed && devices.containsKey(displayId)) {
final CGraphicsDevice gd = devices.remove(displayId);
oldDevices.add(new WeakReference<>(gd));
}
}
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();
}
}
void _displayReconfiguration(int displayId, boolean removed) {
// we ignore the passed parameters and check removed devices ourself
// Note that it is possible that this callback is called when the
// monitors are not added nor removed, but when the video card is
// switched to/from the discrete video card, so we should try to map the
// old to the new devices.
rebuildDevices();
}

@Override
@@ -163,44 +156,74 @@ protected void finalize() throws Throwable {
/**
* (Re)create all CGraphicsDevices, reuses a devices if it is possible.
*/
private void initDevices() {
synchronized (this) {
final Map<Integer, CGraphicsDevice> old = new HashMap<>(devices);
devices.clear();

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, and then
// retrieve actual list of displays.
if (!old.containsKey(mainDisplayID)) {
old.put(mainDisplayID, new CGraphicsDevice(mainDisplayID));
private synchronized void initDevices() {
Map<Integer, CGraphicsDevice> old = new HashMap<>(devices);
devices.clear();
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));
}

int[] displayIDs = getDisplayIDs();
if (displayIDs.length == 0) {
// we could throw AWTError in this case.
displayIDs = new int[]{mainDisplayID};
}
for (int id : displayIDs) {
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();

// unlikely but make sure the main screen is in the list of screens,
// most probably one more "displayReconfiguration" is on the road if not
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();
}
}
}

for (final int id : getDisplayIDs()) {
devices.put(id, old.containsKey(id) ? old.get(id)
: new CGraphicsDevice(id));
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;
}
}
displayChanged();
return null;
}

@Override
public synchronized GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
CGraphicsDevice d = 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;
return devices.get(mainDisplayID);
}

@Override
@@ -41,7 +41,7 @@

/**
* @test
* @bug 4836241 6364134 8232200
* @bug 4836241 6364134 8232200 8252133
* @key headful
* @summary verify that images are restored correctly after display mode
* switches and that no other rendering or crash problems occur

1 comment on commit e5870cf

@bridgekeeper

This comment has been minimized.

Copy link

@bridgekeeper bridgekeeper bot commented on e5870cf Oct 21, 2020

Please sign in to comment.