8305578: X11GraphicsDevice.pGetBounds() is slow in remote X11 sessions

Reviewed-by: avu, serb
This commit is contained in:
Maxim Kartashev 2023-05-24 12:48:37 +00:00 committed by Alexey Ushakov
parent 544978cb76
commit d7245f70e7
2 changed files with 58 additions and 5 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2023, 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
@ -116,6 +116,7 @@ import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
@ -358,6 +359,11 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
} finally {
awtLock();
}
} else {
final XAtom XA_NET_WORKAREA = XAtom.get("_NET_WORKAREA");
final boolean rootWindowWorkareaResized = (ev.get_type() == XConstants.PropertyNotify
&& ev.get_xproperty().get_atom() == XA_NET_WORKAREA.getAtom());
if (rootWindowWorkareaResized) resetScreenInsetsCache();
}
}
});
@ -843,8 +849,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
* When two screens overlap and the first contains a dock(*****), then
* _NET_WORKAREA may start at point x1,y1 and end at point x2,y2.
*/
@Override
public Insets getScreenInsets(final GraphicsConfiguration gc) {
private Insets getScreenInsetsImpl(final GraphicsConfiguration gc) {
GraphicsDevice gd = gc.getDevice();
XNETProtocol np = XWM.getWM().getNETProtocol();
if (np == null || !(gd instanceof X11GraphicsDevice) || !np.active()) {
@ -872,6 +877,30 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
}
}
private void resetScreenInsetsCache() {
final GraphicsDevice[] devices = ((X11GraphicsEnvironment)GraphicsEnvironment.
getLocalGraphicsEnvironment()).getScreenDevices();
for (var gd : devices) {
((X11GraphicsDevice)gd).resetInsets();
}
}
@Override
public Insets getScreenInsets(final GraphicsConfiguration gc) {
final X11GraphicsDevice device = (X11GraphicsDevice) gc.getDevice();
Insets insets = device.getInsets();
if (insets == null) {
synchronized (device) {
insets = device.getInsets();
if (insets == null) {
insets = getScreenInsetsImpl(gc);
device.setInsets(insets);
}
}
}
return (Insets) insets.clone();
}
/*
* The current implementation of disabling background erasing for
* canvases is that we don't set any native background color

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2023, 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
@ -30,6 +30,7 @@ import java.awt.DisplayMode;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Window;
import java.security.AccessController;
@ -37,6 +38,7 @@ import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Objects;
import sun.awt.util.ThreadGroupUtils;
import sun.java2d.SunGraphicsEnvironment;
@ -66,12 +68,15 @@ public final class X11GraphicsDevice extends GraphicsDevice
private static Boolean xrandrExtSupported;
private SunDisplayChanger topLevels = new SunDisplayChanger();
private DisplayMode origDisplayMode;
private volatile Rectangle bounds;
private volatile Insets insets;
private boolean shutdownHookRegistered;
private int scale;
public X11GraphicsDevice(int screennum) {
this.screen = screennum;
this.scale = initScaleFactor();
this.bounds = getBoundsImpl();
}
/**
@ -118,7 +123,7 @@ public final class X11GraphicsDevice extends GraphicsDevice
return Region.clipRound(x / (double)getScaleFactor());
}
public Rectangle getBounds() {
private Rectangle getBoundsImpl() {
Rectangle rect = pGetBounds(getScreen());
if (getScaleFactor() != 1) {
rect.x = scaleDown(rect.x);
@ -129,6 +134,23 @@ public final class X11GraphicsDevice extends GraphicsDevice
return rect;
}
public Rectangle getBounds() {
return bounds.getBounds();
}
public Insets getInsets() {
return insets;
}
public void setInsets(Insets newInsets) {
Objects.requireNonNull(newInsets);
insets = newInsets;
}
public void resetInsets() {
insets = null;
}
/**
* Returns the identification string associated with this graphics
* device.
@ -516,6 +538,8 @@ public final class X11GraphicsDevice extends GraphicsDevice
@Override
public synchronized void displayChanged() {
scale = initScaleFactor();
bounds = getBoundsImpl();
insets = null;
// On X11 the visuals do not change, and therefore we don't need
// to reset the defaultConfig, config, doubleBufferVisuals,
// neither do we need to reset the native data.