mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2026-01-07 17:11:42 +01:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e66f996829 | ||
|
|
8569475930 | ||
|
|
7433067506 | ||
|
|
2e517af41f | ||
|
|
a54096f118 | ||
|
|
d3f0367a19 | ||
|
|
14f93c154e |
@@ -33,7 +33,6 @@ import sun.lwawt.macosx.CFLayer;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Window;
|
||||
|
||||
@@ -150,11 +149,25 @@ public class MTLLayer extends CFLayer {
|
||||
}
|
||||
}
|
||||
|
||||
private final static String[] STAT_NAMES = new String[]{
|
||||
"java2d.native.mtlLayer.drawInMTLContext", // type = 0
|
||||
"java2d.native.mtlLayer.nextDrawable" // type = 1
|
||||
};
|
||||
|
||||
private void addStat(int type, double value) {
|
||||
// Called from the native code when this layer has been presented on screen
|
||||
Component target = peer.getTarget();
|
||||
if (target instanceof Window window) {
|
||||
AWTAccessor.getWindowAccessor().addStat(window,
|
||||
((type >= 0) && (type < STAT_NAMES.length)) ? STAT_NAMES[type] : "undefined", value);
|
||||
}
|
||||
}
|
||||
|
||||
private void countNewFrame() {
|
||||
// Called from the native code when this layer has been presented on screen
|
||||
Component target = peer.getTarget();
|
||||
if (target instanceof Window window) {
|
||||
AWTAccessor.getWindowAccessor().bumpCounter(window, "java2d.native.frames");
|
||||
AWTAccessor.getWindowAccessor().incrementCounter(window, "java2d.native.frames");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +177,7 @@ public class MTLLayer extends CFLayer {
|
||||
// when those attempts are too frequent.
|
||||
Component target = peer.getTarget();
|
||||
if (target instanceof Window window) {
|
||||
AWTAccessor.getWindowAccessor().bumpCounter(window, "java2d.native.framesDropped");
|
||||
AWTAccessor.getWindowAccessor().incrementCounter(window, "java2d.native.framesDropped");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
- (void) stopRedraw:(MTLContext*)mtlc displayID:(jint)displayID force:(BOOL)force;
|
||||
- (void) flushBuffer;
|
||||
- (void) commitCommandBuffer:(MTLContext*)mtlc wait:(BOOL)waitUntilCompleted display:(BOOL)updateDisplay;
|
||||
|
||||
- (void) addStatCallback:(int)type value:(double)value;
|
||||
- (void) countFramePresentedCallback;
|
||||
- (void) countFrameDroppedCallback;
|
||||
@end
|
||||
|
||||
@@ -226,29 +226,32 @@ BOOL MTLLayer_isExtraRedrawEnabled() {
|
||||
}
|
||||
|
||||
// Acquire CAMetalDrawable without blocking:
|
||||
const CFTimeInterval beforeDrawableTime = (TRACE_DISPLAY) ? CACurrentMediaTime() : 0.0;
|
||||
const CFTimeInterval beforeDrawableTime = CACurrentMediaTime();
|
||||
const id<CAMetalDrawable> mtlDrawable = [self nextDrawable];
|
||||
if (mtlDrawable == nil) {
|
||||
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer.blitTexture: nextDrawable is null");
|
||||
return;
|
||||
}
|
||||
const CFTimeInterval nextDrawableTime = (TRACE_DISPLAY) ? CACurrentMediaTime() : 0.0;
|
||||
const CFTimeInterval nextDrawableTime = CACurrentMediaTime();
|
||||
const CFTimeInterval nextDrawableLatency = (nextDrawableTime - beforeDrawableTime);
|
||||
|
||||
// rolling mean weight (lerp):
|
||||
static const NSTimeInterval a = 0.25;
|
||||
|
||||
#if TRACE_DISPLAY_ON
|
||||
const CFTimeInterval nextDrawableLatency = (nextDrawableTime - beforeDrawableTime);
|
||||
if (nextDrawableLatency > 0.0) {
|
||||
[self addStatCallback:1 value:1000.0 * nextDrawableLatency]; // See MTLLayer.STAT_NAMES[1]
|
||||
|
||||
#if TRACE_DISPLAY_ON
|
||||
self.avgNextDrawableTime = nextDrawableLatency * a + self.avgNextDrawableTime * (1.0 - a);
|
||||
}
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"[%.6lf] MTLLayer_blitTexture: drawable(%d) presented"
|
||||
" - nextDrawableLatency = %.3lf ms - average = %.3lf ms",
|
||||
CACurrentMediaTime(), mtlDrawable.drawableID,
|
||||
1000.0 * nextDrawableLatency, 1000.0 * self.avgNextDrawableTime
|
||||
);
|
||||
|
||||
J2dRlsTraceLn(J2D_TRACE_VERBOSE,
|
||||
"[%.6lf] MTLLayer_blitTexture: drawable(%d) presented"
|
||||
" - nextDrawableLatency = %.3lf ms - average = %.3lf ms",
|
||||
CACurrentMediaTime(), mtlDrawable.drawableID,
|
||||
1000.0 * nextDrawableLatency, 1000.0 * self.avgNextDrawableTime
|
||||
);
|
||||
#endif
|
||||
}
|
||||
// Keep Fence from now:
|
||||
releaseFence = NO;
|
||||
|
||||
@@ -389,8 +392,15 @@ BOOL MTLLayer_isExtraRedrawEnabled() {
|
||||
return;
|
||||
}
|
||||
|
||||
const CFTimeInterval beforeMethod = CACurrentMediaTime();
|
||||
|
||||
(*env)->CallVoidMethod(env, javaLayerLocalRef, jm_drawInMTLContext);
|
||||
CHECK_EXCEPTION();
|
||||
|
||||
const CFTimeInterval drawInMTLContextLatency = (CACurrentMediaTime() - beforeMethod);
|
||||
if (drawInMTLContextLatency > 0.0) {
|
||||
[self addStatCallback:0 value:1000.0 * drawInMTLContextLatency]; // See MTLLayer.STAT_NAMES[0]
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, javaLayerLocalRef);
|
||||
}
|
||||
|
||||
@@ -516,6 +526,20 @@ BOOL MTLLayer_isExtraRedrawEnabled() {
|
||||
}
|
||||
}
|
||||
|
||||
- (void) addStatCallback:(int)type value:(double)value {
|
||||
// attach the current thread to the JVM if necessary, and get an env
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnvUncached];
|
||||
GET_MTL_LAYER_CLASS();
|
||||
DECLARE_METHOD(jm_addStatFrame, jc_JavaLayer, "addStat", "(ID)V");
|
||||
|
||||
jobject javaLayerLocalRef = (*env)->NewLocalRef(env, self.javaLayer);
|
||||
if (javaLayerLocalRef != NULL) {
|
||||
(*env)->CallVoidMethod(env, javaLayerLocalRef, jm_addStatFrame, (jint)type, (jdouble)value);
|
||||
CHECK_EXCEPTION();
|
||||
(*env)->DeleteLocalRef(env, javaLayerLocalRef);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) countFrameDroppedCallback {
|
||||
// attach the current thread to the JVM if necessary, and get an env
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnvUncached];
|
||||
|
||||
@@ -34,7 +34,6 @@ import java.awt.event.WindowFocusListener;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.event.WindowStateListener;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.im.InputContext;
|
||||
import java.awt.image.BufferStrategy;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
@@ -44,6 +43,7 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OptionalDataException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Native;
|
||||
@@ -53,12 +53,15 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EventListener;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@@ -69,11 +72,14 @@ import javax.accessibility.AccessibleState;
|
||||
import javax.accessibility.AccessibleStateSet;
|
||||
|
||||
import com.jetbrains.exported.JBRApi;
|
||||
import jdk.internal.misc.InnocuousThread;
|
||||
import sun.awt.AWTAccessor;
|
||||
import sun.awt.AppContext;
|
||||
import sun.awt.DebugSettings;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.util.IdentityArrayList;
|
||||
import sun.awt.util.ThreadGroupUtils;
|
||||
import sun.java2d.marlin.stats.StatDouble;
|
||||
import sun.java2d.pipe.Region;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
@@ -1153,45 +1159,51 @@ public class Window extends Container implements Accessible {
|
||||
}
|
||||
|
||||
void doDispose() {
|
||||
class DisposeAction implements Runnable {
|
||||
public void run() {
|
||||
disposing = true;
|
||||
try {
|
||||
// Check if this window is the fullscreen window for the
|
||||
// device. Exit the fullscreen mode prior to disposing
|
||||
// of the window if that's the case.
|
||||
GraphicsDevice gd = getGraphicsConfiguration().getDevice();
|
||||
if (gd.getFullScreenWindow() == Window.this) {
|
||||
gd.setFullScreenWindow(null);
|
||||
}
|
||||
final class DisposeAction implements Runnable {
|
||||
public void run() {
|
||||
final Window window = Window.this;
|
||||
|
||||
Object[] ownedWindowArray;
|
||||
synchronized(ownedWindowList) {
|
||||
ownedWindowArray = new Object[ownedWindowList.size()];
|
||||
ownedWindowList.copyInto(ownedWindowArray);
|
||||
}
|
||||
for (int i = 0; i < ownedWindowArray.length; i++) {
|
||||
Window child = (Window) (((WeakReference)
|
||||
(ownedWindowArray[i])).get());
|
||||
if (child != null) {
|
||||
child.disposeImpl();
|
||||
// dump stats if needed:
|
||||
AWTAccessor.getWindowAccessor().dumpStats(window, true, null);
|
||||
|
||||
disposing = true;
|
||||
try {
|
||||
// Check if this window is the fullscreen window for the
|
||||
// device. Exit the fullscreen mode prior to disposing
|
||||
// of the window if that's the case.
|
||||
GraphicsDevice gd = getGraphicsConfiguration().getDevice();
|
||||
if (gd.getFullScreenWindow() == window) {
|
||||
gd.setFullScreenWindow(null);
|
||||
}
|
||||
}
|
||||
hide();
|
||||
beforeFirstShow = true;
|
||||
removeNotify();
|
||||
synchronized (inputContextLock) {
|
||||
if (inputContext != null) {
|
||||
inputContext.dispose();
|
||||
inputContext = null;
|
||||
|
||||
Object[] ownedWindowArray;
|
||||
synchronized(ownedWindowList) {
|
||||
ownedWindowArray = new Object[ownedWindowList.size()];
|
||||
ownedWindowList.copyInto(ownedWindowArray);
|
||||
}
|
||||
for (int i = 0; i < ownedWindowArray.length; i++) {
|
||||
Window child = (Window) (((WeakReference)
|
||||
(ownedWindowArray[i])).get());
|
||||
if (child != null) {
|
||||
child.disposeImpl();
|
||||
}
|
||||
}
|
||||
hide();
|
||||
beforeFirstShow = true;
|
||||
removeNotify();
|
||||
synchronized (inputContextLock) {
|
||||
if (inputContext != null) {
|
||||
inputContext.dispose();
|
||||
inputContext = null;
|
||||
}
|
||||
}
|
||||
clearCurrentFocusCycleRootOnHide();
|
||||
} finally {
|
||||
disposing = false;
|
||||
}
|
||||
clearCurrentFocusCycleRootOnHide();
|
||||
} finally {
|
||||
disposing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean fireWindowClosedEvent = isDisplayable();
|
||||
DisposeAction action = new DisposeAction();
|
||||
if (EventQueue.isDispatchThread()) {
|
||||
@@ -4164,8 +4176,36 @@ public class Window extends Container implements Accessible {
|
||||
return value;
|
||||
}
|
||||
|
||||
private final static String STATS_ALL_SUFFIX = ".all";
|
||||
private final static String SYSTEM_PROPERTY_COUNTERS;
|
||||
|
||||
private final static boolean USE_COUNTERS;
|
||||
private final static boolean TRACE_ALL_COUNTERS;
|
||||
private final static boolean TRACE_STD_ERR;
|
||||
|
||||
private final static int TRACE_CAPACITY;
|
||||
|
||||
private final static boolean TRACE_COUNTERS = true;
|
||||
private final static boolean DUMP_STATS = true;
|
||||
|
||||
// thread dump interval (ms)
|
||||
static final long DUMP_INTERVAL = 10 * 1000L;
|
||||
|
||||
private static PrintStream getTraceStdStream() {
|
||||
// get live std stream:
|
||||
return TRACE_STD_ERR ? System.err : System.out;
|
||||
}
|
||||
|
||||
static {
|
||||
String counters = System.getProperty("awt.window.counters");
|
||||
SYSTEM_PROPERTY_COUNTERS = System.getProperty("awt.window.counters");
|
||||
USE_COUNTERS = (SYSTEM_PROPERTY_COUNTERS != null);
|
||||
|
||||
TRACE_ALL_COUNTERS = USE_COUNTERS && (Objects.equals(SYSTEM_PROPERTY_COUNTERS, "")
|
||||
|| Objects.equals(SYSTEM_PROPERTY_COUNTERS, "stderr")
|
||||
|| Objects.equals(SYSTEM_PROPERTY_COUNTERS, "stdout"));
|
||||
|
||||
TRACE_STD_ERR = USE_COUNTERS && SYSTEM_PROPERTY_COUNTERS.contains("stderr");
|
||||
TRACE_CAPACITY = USE_COUNTERS ? 8 : 0;
|
||||
|
||||
AWTAccessor.setWindowAccessor(new AWTAccessor.WindowAccessor() {
|
||||
public void updateWindow(Window window) {
|
||||
@@ -4202,100 +4242,201 @@ public class Window extends Container implements Accessible {
|
||||
|
||||
public boolean countersEnabled(Window w) {
|
||||
// May want to selectively enable or disable counters per window
|
||||
return counters != null;
|
||||
return USE_COUNTERS;
|
||||
}
|
||||
|
||||
public void bumpCounter(Window w, String counterName) {
|
||||
Objects.requireNonNull(w);
|
||||
Objects.requireNonNull(counterName);
|
||||
private final static long NANO_IN_SEC = java.util.concurrent.TimeUnit.SECONDS.toNanos(1);
|
||||
|
||||
PerfCounter newCounter;
|
||||
long curTimeNanos = System.nanoTime();
|
||||
synchronized (w.perfCounters) {
|
||||
newCounter = w.perfCounters.compute(counterName, (k, v) ->
|
||||
v == null
|
||||
? new PerfCounter(curTimeNanos, 1L)
|
||||
: new PerfCounter(curTimeNanos, v.value + 1));
|
||||
}
|
||||
PerfCounter prevCounter;
|
||||
synchronized (w.perfCountersPrev) {
|
||||
prevCounter = w.perfCountersPrev.putIfAbsent(counterName, newCounter);
|
||||
}
|
||||
if (prevCounter != null) {
|
||||
long nanosInSecond = java.util.concurrent.TimeUnit.SECONDS.toNanos(1);
|
||||
long timeDeltaNanos = curTimeNanos - prevCounter.updateTimeNanos;
|
||||
if (timeDeltaNanos > nanosInSecond) {
|
||||
long valPerSecond = (long) ((double) (newCounter.value - prevCounter.value)
|
||||
* nanosInSecond / timeDeltaNanos);
|
||||
boolean traceAllCounters = Objects.equals(counters, "")
|
||||
|| Objects.equals(counters, "stdout")
|
||||
|| Objects.equals(counters, "stderr");
|
||||
boolean traceEnabled = traceAllCounters || (counters != null && counters.contains(counterName));
|
||||
if (traceEnabled) {
|
||||
if (counters.contains("stderr")) {
|
||||
System.err.println(counterName + " per second: " + valPerSecond);
|
||||
} else {
|
||||
System.out.println(counterName + " per second: " + valPerSecond);
|
||||
}
|
||||
}
|
||||
if (perfLog.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
perfLog.fine(counterName + " per second: " + valPerSecond);
|
||||
public void incrementCounter(final Window w, final String counterName) {
|
||||
if (USE_COUNTERS) {
|
||||
Objects.requireNonNull(w);
|
||||
Objects.requireNonNull(counterName);
|
||||
|
||||
final long curTimeNanos = System.nanoTime();
|
||||
// use try-catch to avoid throwing runtime exception to native JNI callers!
|
||||
try {
|
||||
PerfCounter newCounter, prevCounter;
|
||||
synchronized (w.perfCounters) {
|
||||
newCounter = w.perfCounters.compute(counterName, (_, v) ->
|
||||
v == null
|
||||
? new PerfCounter(curTimeNanos, 1L)
|
||||
: new PerfCounter(curTimeNanos, v.value + 1));
|
||||
}
|
||||
synchronized (w.perfCountersPrev) {
|
||||
w.perfCountersPrev.put(counterName, newCounter);
|
||||
prevCounter = w.perfCountersPrev.putIfAbsent(counterName, newCounter);
|
||||
}
|
||||
if (prevCounter != null) {
|
||||
final long timeDeltaNanos = curTimeNanos - prevCounter.updateTimeNanos;
|
||||
if (timeDeltaNanos > NANO_IN_SEC) {
|
||||
final double valPerSecond = (double) (newCounter.value - prevCounter.value)
|
||||
* NANO_IN_SEC / timeDeltaNanos;
|
||||
|
||||
synchronized (w.perfCountersPrev) {
|
||||
w.perfCountersPrev.put(counterName, newCounter);
|
||||
}
|
||||
addStat(w, counterName, valPerSecond);
|
||||
if (TRACE_COUNTERS) {
|
||||
dumpCounter(counterName, valPerSecond);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException re) {
|
||||
perfLog.severe("incrementCounter: failed", re);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addStat(final Window w, final String statName, final double value) {
|
||||
if (USE_COUNTERS && Double.isFinite(value)) {
|
||||
Objects.requireNonNull(w);
|
||||
Objects.requireNonNull(statName);
|
||||
|
||||
// use try-catch to avoid throwing runtime exception to native JNI callers!
|
||||
try {
|
||||
synchronized (w.perfStats) {
|
||||
StatDouble stat = w.perfStats.computeIfAbsent(statName, StatDouble::new);
|
||||
stat.add(value);
|
||||
stat = w.perfStats.computeIfAbsent(statName + STATS_ALL_SUFFIX, StatDouble::new);
|
||||
stat.add(value);
|
||||
}
|
||||
} catch (RuntimeException re) {
|
||||
perfLog.severe("addStat: failed", re);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getCounter(final Window w, final String counterName) {
|
||||
if (USE_COUNTERS) {
|
||||
Objects.requireNonNull(w);
|
||||
Objects.requireNonNull(counterName);
|
||||
|
||||
synchronized (w.perfCounters) {
|
||||
PerfCounter counter = w.perfCounters.get(counterName);
|
||||
return counter != null ? counter.value : -1L;
|
||||
}
|
||||
}
|
||||
return -1L;
|
||||
}
|
||||
|
||||
public double getCounterPerSecond(final Window w, final String counterName) {
|
||||
if (USE_COUNTERS) {
|
||||
Objects.requireNonNull(w);
|
||||
Objects.requireNonNull(counterName);
|
||||
|
||||
PerfCounter newCounter, prevCounter;
|
||||
synchronized (w.perfCounters) {
|
||||
newCounter = w.perfCounters.get(counterName);
|
||||
}
|
||||
synchronized (w.perfCountersPrev) {
|
||||
prevCounter = w.perfCountersPrev.get(counterName);
|
||||
}
|
||||
|
||||
if (newCounter != null && prevCounter != null) {
|
||||
final long timeDeltaNanos = newCounter.updateTimeNanos - prevCounter.updateTimeNanos;
|
||||
// Note that this time delta will usually be above one second.
|
||||
if (timeDeltaNanos > 0L) {
|
||||
return (double) (newCounter.value - prevCounter.value) * NANO_IN_SEC / timeDeltaNanos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
public void dumpStats(final Window w, final boolean reset, StringBuilder sb) {
|
||||
if (USE_COUNTERS) {
|
||||
synchronized (w.perfStats) {
|
||||
boolean header = false;
|
||||
|
||||
for (final StatDouble stat : w.perfStats.values()) {
|
||||
if (stat.shouldLog()) {
|
||||
final boolean traceEnabled = TRACE_ALL_COUNTERS || SYSTEM_PROPERTY_COUNTERS.contains(stat.name);
|
||||
if (!header) {
|
||||
header = true;
|
||||
doLog(String.format("* Window['%s'@%s]:",
|
||||
(w instanceof Frame ? ((Frame) w).getTitle() : ""),
|
||||
Integer.toHexString(System.identityHashCode(w))),
|
||||
traceEnabled);
|
||||
}
|
||||
// format:
|
||||
if (sb == null) {
|
||||
sb = new StringBuilder(128);
|
||||
}
|
||||
sb.setLength(0);
|
||||
sb.append(" - ");
|
||||
stat.toString(sb);
|
||||
doLog(sb.toString(), traceEnabled);
|
||||
|
||||
if (reset && !stat.name.endsWith(STATS_ALL_SUFFIX)) {
|
||||
stat.reset();
|
||||
} else {
|
||||
stat.updateLastLogCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getCounter(Window w, String counterName) {
|
||||
Objects.requireNonNull(w);
|
||||
Objects.requireNonNull(counterName);
|
||||
|
||||
synchronized (w.perfCounters) {
|
||||
PerfCounter counter = w.perfCounters.get(counterName);
|
||||
return counter != null ? counter.value : -1L;
|
||||
private static void dumpCounter(final String counterName, final double valPerSecond) {
|
||||
if (USE_COUNTERS) {
|
||||
doLog(String.format("%s per second: %.2f", counterName, valPerSecond),
|
||||
TRACE_ALL_COUNTERS || SYSTEM_PROPERTY_COUNTERS.contains(counterName));
|
||||
}
|
||||
}
|
||||
|
||||
public long getCounterPerSecond(Window w, String counterName) {
|
||||
Objects.requireNonNull(w);
|
||||
Objects.requireNonNull(counterName);
|
||||
|
||||
PerfCounter newCounter;
|
||||
PerfCounter prevCounter;
|
||||
|
||||
synchronized (w.perfCounters) {
|
||||
newCounter = w.perfCounters.get(counterName);
|
||||
private static void doLog(final String msg, final boolean traceEnabled) {
|
||||
if (traceEnabled) {
|
||||
getTraceStdStream().println(msg);
|
||||
}
|
||||
|
||||
synchronized (w.perfCountersPrev) {
|
||||
prevCounter = w.perfCountersPrev.get(counterName);
|
||||
if (perfLog.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
perfLog.fine(msg);
|
||||
}
|
||||
|
||||
if (newCounter != null && prevCounter != null) {
|
||||
long timeDeltaNanos = newCounter.updateTimeNanos - prevCounter.updateTimeNanos;
|
||||
// Note that this time delta will usually be above one second.
|
||||
if (timeDeltaNanos > 0) {
|
||||
long nanosInSecond = java.util.concurrent.TimeUnit.SECONDS.toNanos(1);
|
||||
long valPerSecond = (long) ((double) (newCounter.value - prevCounter.value)
|
||||
* nanosInSecond / timeDeltaNanos);
|
||||
return valPerSecond;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}); // WindowAccessor
|
||||
|
||||
if (USE_COUNTERS) {
|
||||
final Runnable dumper = new Runnable() {
|
||||
private final static StringBuilder sb = new StringBuilder(128);
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
getTraceStdStream().printf("--- WindowStats dump at: %s ---\n", new java.util.Date());
|
||||
|
||||
final AWTAccessor.WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
|
||||
|
||||
for (Window window : Window.getWindows()) {
|
||||
// dump stats if needed:
|
||||
windowAccessor.dumpStats(window, true, sb);
|
||||
}
|
||||
getTraceStdStream().println("-----");
|
||||
}
|
||||
};
|
||||
final Thread hook = InnocuousThread.newSystemThread("WindowStatsHook", dumper);
|
||||
hook.setDaemon(true);
|
||||
hook.setContextClassLoader(null);
|
||||
Runtime.getRuntime().addShutdownHook(hook);
|
||||
|
||||
if (DUMP_STATS) {
|
||||
final Timer statTimer = new Timer("WindowStats");
|
||||
statTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
dumper.run();
|
||||
}
|
||||
}, DUMP_INTERVAL, DUMP_INTERVAL);
|
||||
}
|
||||
}
|
||||
} // static
|
||||
|
||||
// a window doesn't need to be updated in the Z-order.
|
||||
@Override
|
||||
void updateZOrder() {}
|
||||
|
||||
private record PerfCounter(Long updateTimeNanos, Long value) {}
|
||||
private record PerfCounter(long updateTimeNanos, long value) {}
|
||||
|
||||
private transient final Map<String, PerfCounter> perfCounters = new HashMap<>(4);
|
||||
private transient final Map<String, PerfCounter> perfCountersPrev = new HashMap<>(4);
|
||||
private transient final HashMap<String, PerfCounter> perfCounters = (USE_COUNTERS) ? new HashMap<>(TRACE_CAPACITY) : null;
|
||||
private transient final HashMap<String, PerfCounter> perfCountersPrev = (USE_COUNTERS) ? new HashMap<>(TRACE_CAPACITY) : null;
|
||||
private transient final LinkedHashMap<String, StatDouble> perfStats = (USE_COUNTERS) ? new LinkedHashMap<>(TRACE_CAPACITY) : null;
|
||||
|
||||
} // class Window
|
||||
|
||||
|
||||
@@ -27,10 +27,7 @@ package javax.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.VolatileImage;
|
||||
import java.awt.peer.WindowPeer;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.applet.*;
|
||||
@@ -43,14 +40,12 @@ import sun.java2d.SunGraphicsEnvironment;
|
||||
|
||||
import com.sun.java.swing.SwingUtilities3;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.pipe.Region;
|
||||
import sun.swing.SwingAccessor;
|
||||
import sun.swing.SwingUtilities2;
|
||||
import sun.swing.SwingUtilities2.RepaintListener;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* This class manages repaint requests, allowing the number
|
||||
@@ -755,7 +750,7 @@ public class RepaintManager
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.forEach(w -> AWTAccessor.getWindowAccessor()
|
||||
.bumpCounter(w, "swing.RepaintManager.updateWindows"));
|
||||
.incrementCounter(w, "swing.RepaintManager.updateWindows"));
|
||||
|
||||
if (Toolkit.getDefaultToolkit() instanceof SunToolkit sunToolkit &&
|
||||
sunToolkit.needUpdateWindow()) {
|
||||
@@ -774,14 +769,14 @@ public class RepaintManager
|
||||
|
||||
for (Window window : windows) {
|
||||
AWTAccessor.getWindowAccessor().updateWindow(window);
|
||||
AWTAccessor.getWindowAccessor().bumpCounter(window, "swing.RepaintManager.updateWindows");
|
||||
AWTAccessor.getWindowAccessor().incrementCounter(window, "swing.RepaintManager.updateWindows");
|
||||
}
|
||||
} else {
|
||||
dirtyComponents.keySet().stream()
|
||||
.map(c -> c instanceof Window w ? w : SwingUtilities.getWindowAncestor(c))
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(w -> AWTAccessor.getWindowAccessor()
|
||||
.bumpCounter(w, "swing.RepaintManager.updateWindows"));
|
||||
.incrementCounter(w, "swing.RepaintManager.updateWindows"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ import java.awt.event.InputEvent;
|
||||
import java.awt.event.InvocationEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.BufferStrategy;
|
||||
import java.awt.peer.ComponentPeer;
|
||||
|
||||
@@ -329,10 +328,15 @@ public final class AWTAccessor {
|
||||
*/
|
||||
Window[] getOwnedWindows(Window w);
|
||||
|
||||
/* JBR Window counters API */
|
||||
boolean countersEnabled(Window w);
|
||||
void bumpCounter(Window w, String counterName);
|
||||
void incrementCounter(Window w, String counterName);
|
||||
void addStat(Window w, String statName, double value);
|
||||
|
||||
long getCounter(Window w, String counterName);
|
||||
long getCounterPerSecond(Window w, String counterName);
|
||||
double getCounterPerSecond(Window w, String counterName);
|
||||
|
||||
void dumpStats(Window w, boolean reset, StringBuilder sb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,8 @@ package sun.java2d.marlin;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import jdk.internal.misc.InnocuousThread;
|
||||
import jdk.internal.ref.CleanerFactory;
|
||||
import sun.java2d.marlin.ArrayCacheConst.CacheStats;
|
||||
import static sun.java2d.marlin.MarlinUtils.logInfo;
|
||||
@@ -383,16 +385,8 @@ public final class RendererStats implements MarlinConst {
|
||||
= new ConcurrentLinkedQueue<>();
|
||||
|
||||
private RendererStatsHolder() {
|
||||
final Thread hook = new Thread(
|
||||
MarlinUtils.getRootThreadGroup(),
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dump();
|
||||
}
|
||||
},
|
||||
"MarlinStatsHook"
|
||||
);
|
||||
final Thread hook = InnocuousThread.newSystemThread("MarlinStatsHook", () -> dump());
|
||||
hook.setDaemon(true);
|
||||
hook.setContextClassLoader(null);
|
||||
Runtime.getRuntime().addShutdownHook(hook);
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2025 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.java2d.marlin.stats;
|
||||
|
||||
import static sun.java2d.marlin.stats.StatLong.trimTo3Digits;
|
||||
|
||||
/**
|
||||
* Statistics on double values
|
||||
*/
|
||||
public final class StatDouble {
|
||||
// rolling mean weight (lerp):
|
||||
private final static double EMA_ALPHA = 0.25;
|
||||
private final static double EMA_ONE_MINUS_ALPHA = 1.0 - EMA_ALPHA;
|
||||
|
||||
public final String name;
|
||||
private long count, lastLogCount;
|
||||
private double min, max, mean, ema_mean = 0.0, squaredError;
|
||||
|
||||
public StatDouble(final String name) {
|
||||
this.name = name;
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
count = 0L;
|
||||
lastLogCount = 0L;
|
||||
min = Double.POSITIVE_INFINITY;
|
||||
max = Double.NEGATIVE_INFINITY;
|
||||
mean = 0.0;
|
||||
// skip ema_mean = 0.0;
|
||||
squaredError = 0.0;
|
||||
}
|
||||
|
||||
public void add(final double val) {
|
||||
count++;
|
||||
if (val < min) {
|
||||
min = val;
|
||||
}
|
||||
if (val > max) {
|
||||
max = val;
|
||||
}
|
||||
// Exponential smoothing (EMA):
|
||||
ema_mean = EMA_ALPHA * val + EMA_ONE_MINUS_ALPHA * ema_mean;
|
||||
// Welford's algorithm:
|
||||
final double oldMean = mean;
|
||||
mean += (val - mean) / count;
|
||||
squaredError += (val - mean) * (val - oldMean);
|
||||
}
|
||||
|
||||
public boolean shouldLog() {
|
||||
return (count > lastLogCount);
|
||||
}
|
||||
|
||||
public void updateLastLogCount() {
|
||||
this.lastLogCount = this.count;
|
||||
}
|
||||
|
||||
public long count() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public double min() {
|
||||
return (count != 0L) ? min : Double.NaN;
|
||||
}
|
||||
|
||||
public double max() {
|
||||
return (count != 0L) ? max : Double.NaN;
|
||||
}
|
||||
|
||||
public double mean() {
|
||||
return (count != 0L) ? mean : Double.NaN;
|
||||
}
|
||||
|
||||
public double ema() {
|
||||
return (count != 0L) ? ema_mean : Double.NaN;
|
||||
}
|
||||
|
||||
public double variance() {
|
||||
return (count != 0L) ? (squaredError / (count - 1L)) : Double.NaN;
|
||||
}
|
||||
|
||||
public double stddev() {
|
||||
return (count != 0L) ? Math.sqrt(variance()) : Double.NaN;
|
||||
}
|
||||
|
||||
public double total() {
|
||||
return (count != 0L) ? (mean() * count) : Double.NaN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(new StringBuilder(128)).toString();
|
||||
}
|
||||
|
||||
public StringBuilder toString(final StringBuilder sb) {
|
||||
sb.append(name).append('[').append(count);
|
||||
sb.append("] sum: ").append(trimTo3Digits(total()));
|
||||
sb.append(" avg: ").append(trimTo3Digits(mean()));
|
||||
sb.append(" stddev: ").append(trimTo3Digits(stddev()));
|
||||
sb.append(" ema: ").append(trimTo3Digits(ema()));
|
||||
sb.append(" [").append(trimTo3Digits(min())).append(" - ").append(trimTo3Digits(max())).append("]");
|
||||
return sb;
|
||||
}
|
||||
}
|
||||
@@ -31,20 +31,18 @@ package sun.java2d.marlin.stats;
|
||||
public class StatLong {
|
||||
|
||||
public final String name;
|
||||
public long count = 0L;
|
||||
public long sum = 0L;
|
||||
public long min = Integer.MAX_VALUE;
|
||||
public long max = Integer.MIN_VALUE;
|
||||
public long count, sum, min, max;
|
||||
|
||||
public StatLong(final String name) {
|
||||
this.name = name;
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
count = 0L;
|
||||
sum = 0L;
|
||||
min = Integer.MAX_VALUE;
|
||||
max = Integer.MIN_VALUE;
|
||||
min = Long.MAX_VALUE;
|
||||
max = Long.MIN_VALUE;
|
||||
}
|
||||
|
||||
public void add(final int val) {
|
||||
@@ -78,7 +76,7 @@ public class StatLong {
|
||||
sb.append(name).append('[').append(count);
|
||||
sb.append("] sum: ").append(sum).append(" avg: ");
|
||||
sb.append(trimTo3Digits(((double) sum) / count));
|
||||
sb.append(" [").append(min).append(" | ").append(max).append("]");
|
||||
sb.append(" [").append(min).append(" - ").append(max).append("]");
|
||||
return sb;
|
||||
}
|
||||
|
||||
@@ -89,7 +87,7 @@ public class StatLong {
|
||||
* @return double value with only 3 decimal digits
|
||||
*/
|
||||
public static double trimTo3Digits(final double value) {
|
||||
return ((long) (1e3d * value)) / 1e3d;
|
||||
return Double.isFinite(value) ? ((long) (1e3d * value)) / 1e3d : Double.NaN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ import sun.util.logging.PlatformLogger;
|
||||
import java.awt.Toolkit;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class VKEnv {
|
||||
@@ -109,16 +108,20 @@ public final class VKEnv {
|
||||
state = newState;
|
||||
|
||||
if (Options.verbose || log.isLoggable(PlatformLogger.Level.FINE)) {
|
||||
String message;
|
||||
StringBuilder msg = new StringBuilder("Vulkan rendering enabled: ");
|
||||
if (isVulkanEnabled()) {
|
||||
message = "Vulkan rendering enabled: YES" +
|
||||
"\n presentation enabled: " + (isPresentationEnabled() ? "YES" : "NO") +
|
||||
"\n accelerated surface data enabled: " + (isSurfaceDataAccelerated() ? "YES" : "NO") +
|
||||
"\n devices:" + Stream.of(devices).map(d -> (d == defaultDevice ?
|
||||
"\n *" : "\n ") + d.getName()).collect(Collectors.joining());
|
||||
msg.append("YES")
|
||||
.append("\n Presentation enabled: ").append(isPresentationEnabled() ? "YES" : "NO")
|
||||
.append("\n Accelerated surface data enabled: ").append(isSurfaceDataAccelerated() ? "YES" : "NO")
|
||||
.append("\n Devices:");
|
||||
for (int i = 0; i < devices.length; i++) {
|
||||
VKGPU d = devices[i];
|
||||
msg.append(d == defaultDevice ? "\n *" : "\n ").append(i).append(": ").append(d.getName());
|
||||
}
|
||||
} else {
|
||||
message = "Vulkan rendering enabled: NO";
|
||||
msg.append("NO");
|
||||
}
|
||||
String message = msg.toString();
|
||||
if (Options.verbose) {
|
||||
System.err.println(message);
|
||||
}
|
||||
|
||||
@@ -292,7 +292,15 @@ VkBool32 VKSD_ConfigureWindowSurface(VKWinSDOps* vkwinsdo) {
|
||||
}
|
||||
|
||||
static void VKSD_OnDispose(JNIEnv* env, SurfaceDataOps* ops) {
|
||||
// We are being called from the disposer thread, RQ might be working in parallel.
|
||||
// VKRenderQueue.lock/unlock is equivalent to AWT_LOCK/AWT_UNLOCK,
|
||||
// but those are only available in the toolkit-specific part of AWT, so we call RQ there.
|
||||
jobject rq = JNU_CallStaticMethodByName(env, NULL,
|
||||
"sun/java2d/vulkan/VKRenderQueue", "getInstance", "()Lsun/java2d/vulkan/VKRenderQueue;").l;
|
||||
JNU_CallMethodByName(env, NULL, rq, "lock", "()V");
|
||||
VKSD_ResetSurface((VKSDOps*) ops);
|
||||
JNU_CallMethodByName(env, NULL, rq, "unlock", "()V");
|
||||
(*env)->DeleteLocalRef(env, rq);
|
||||
}
|
||||
|
||||
JNIEXPORT VKSDOps* VKSD_CreateSurface(JNIEnv* env, jobject vksd, jint type, jint format, jint backgroundRGB,
|
||||
|
||||
@@ -76,8 +76,10 @@ public class GtkFrameDecoration extends FullFrameDecorationHelper {
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
// Determine buttons' bounds, etc.
|
||||
nativePrePaint(nativePtr, peer.getWidth());
|
||||
super.paint(g);
|
||||
nativePrePaint(nativePtr, peer.getWidth(), peer.getHeight());
|
||||
if (peer.getWidth() >= titleBarMinWidth && peer.getHeight() >= titleBarHeight) {
|
||||
super.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,6 +87,9 @@ public class GtkFrameDecoration extends FullFrameDecorationHelper {
|
||||
int width = peer.getWidth();
|
||||
int height = titleBarHeight;
|
||||
|
||||
assert width >= titleBarMinWidth;
|
||||
assert peer.getHeight() >= titleBarHeight;
|
||||
|
||||
double scale = ((WLGraphicsConfig) peer.getGraphicsConfiguration()).getEffectiveScale();
|
||||
g2d.setBackground(new Color(0, true));
|
||||
g2d.clearRect(0, 0, width, height);
|
||||
@@ -217,5 +222,5 @@ public class GtkFrameDecoration extends FullFrameDecorationHelper {
|
||||
String title, int buttonsState);
|
||||
private native int nativeGetIntProperty(long nativePtr, String name);
|
||||
private native void nativeNotifyConfigured(long nativePtr, boolean active, boolean maximized, boolean fullscreen);
|
||||
private native void nativePrePaint(long nativePtr, int width);
|
||||
private native void nativePrePaint(long nativePtr, int width, int height);
|
||||
}
|
||||
|
||||
@@ -30,14 +30,12 @@ import sun.awt.AWTAccessor;
|
||||
import sun.awt.AWTAccessor.ComponentAccessor;
|
||||
import sun.awt.PaintEventDispatcher;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.SurfacePixelGrabber;
|
||||
import sun.awt.event.IgnorePaintEvent;
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.pipe.Region;
|
||||
import sun.java2d.vulkan.VKSurfaceData;
|
||||
import sun.java2d.wl.WLSurfaceDataExt;
|
||||
import sun.java2d.wl.WLSurfaceSizeListener;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
@@ -90,8 +88,8 @@ public class WLComponentPeer implements ComponentPeer, WLSurfaceSizeListener {
|
||||
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.wl.focus.WLComponentPeer");
|
||||
private static final PlatformLogger popupLog = PlatformLogger.getLogger("sun.awt.wl.popup.WLComponentPeer");
|
||||
|
||||
private static final int MINIMUM_WIDTH = 1;
|
||||
private static final int MINIMUM_HEIGHT = 1;
|
||||
protected static final int MINIMUM_WIDTH = 1;
|
||||
protected static final int MINIMUM_HEIGHT = 1;
|
||||
|
||||
private final Object stateLock = new Object();
|
||||
|
||||
@@ -859,8 +857,10 @@ public class WLComponentPeer implements ComponentPeer, WLSurfaceSizeListener {
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize() {
|
||||
int shadowSize = (int) Math.ceil(shadow.getSize() * 4);
|
||||
return new Dimension(shadowSize, shadowSize);
|
||||
int shadowSize = shadow != null ? (int) Math.ceil(shadow.getSize() * 4) : 0;
|
||||
return shadowSize == 0
|
||||
? new Dimension(MINIMUM_WIDTH, MINIMUM_HEIGHT)
|
||||
: new Dimension(shadowSize, shadowSize);
|
||||
}
|
||||
|
||||
void showWindowMenu(long serial, int x, int y) {
|
||||
@@ -1756,9 +1756,12 @@ public class WLComponentPeer implements ComponentPeer, WLSurfaceSizeListener {
|
||||
|
||||
private Dimension constrainSize(int width, int height) {
|
||||
Dimension maxBounds = getMaxBufferBounds();
|
||||
Dimension minSize = getMinimumSize();
|
||||
minSize.width = Math.max(MINIMUM_WIDTH, minSize.width);
|
||||
minSize.height = Math.max(MINIMUM_HEIGHT, minSize.height);
|
||||
return new Dimension(
|
||||
Math.max(Math.min(width, maxBounds.width), MINIMUM_WIDTH),
|
||||
Math.max(Math.min(height, maxBounds.height), MINIMUM_HEIGHT));
|
||||
Math.max(Math.min(width, maxBounds.width), minSize.width),
|
||||
Math.max(Math.min(height, maxBounds.height), minSize.height));
|
||||
}
|
||||
|
||||
private Dimension constrainSize(Dimension bounds) {
|
||||
|
||||
@@ -88,7 +88,7 @@ public class WLDataDevice {
|
||||
private static native void dispatchDataSourceQueueImpl(long nativePtr);
|
||||
private static native void setSelectionImpl(int protocol, long nativePtr, long dataOfferNativePtr, long serial);
|
||||
private static native void startDragImpl(long nativePtr, long dataOfferNativePtr,
|
||||
long originSurfaceNativePtr, long iconNativePtr, long serial);
|
||||
long originSurfaceNativePtr, long serial);
|
||||
|
||||
public boolean isProtocolSupported(int protocol) {
|
||||
return isProtocolSupportedImpl(nativePtr, protocol);
|
||||
@@ -98,8 +98,8 @@ public class WLDataDevice {
|
||||
setSelectionImpl(protocol, nativePtr, (source == null) ? 0 : source.getNativePtr(), serial);
|
||||
}
|
||||
|
||||
public void startDrag(WLDataSource source, long originSurfaceNativePtr, long iconNativePtr, long serial) {
|
||||
startDragImpl(nativePtr, source.getNativePtr(), originSurfaceNativePtr, iconNativePtr, serial);
|
||||
public void startDrag(WLDataSource source, long originSurfaceNativePtr, long serial) {
|
||||
startDragImpl(nativePtr, source.getNativePtr(), originSurfaceNativePtr, serial);
|
||||
}
|
||||
|
||||
public WLClipboard getSystemClipboard() {
|
||||
|
||||
@@ -25,7 +25,10 @@
|
||||
|
||||
package sun.awt.wl;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class WLDataSource {
|
||||
@@ -44,6 +47,8 @@ public class WLDataSource {
|
||||
|
||||
private static native void setDnDActionsImpl(long nativePtr, int actions);
|
||||
|
||||
private static native void setDnDIconImpl(long nativePtr, int width, int height, int offsetX, int offsetY, int[] pixels);
|
||||
|
||||
WLDataSource(WLDataDevice dataDevice, int protocol, Transferable data) {
|
||||
var wlDataTransferer = (WLDataTransferer) WLDataTransferer.getInstance();
|
||||
|
||||
@@ -91,6 +96,31 @@ public class WLDataSource {
|
||||
setDnDActionsImpl(nativePtr, actions);
|
||||
}
|
||||
|
||||
public void setDnDIcon(Image image, int offsetX, int offsetY) {
|
||||
if (nativePtr == 0) {
|
||||
throw new IllegalStateException("Native pointer is null");
|
||||
}
|
||||
|
||||
int width = image.getWidth(null);
|
||||
int height = image.getHeight(null);
|
||||
int[] pixels = new int[width * height];
|
||||
|
||||
if (image instanceof BufferedImage) {
|
||||
// NOTE: no need to ensure that the BufferedImage is TYPE_INT_ARGB,
|
||||
// getRGB() does pixel format conversion automatically
|
||||
((BufferedImage) image).getRGB(0, 0, width, height, pixels, 0, width);
|
||||
} else {
|
||||
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = bufferedImage.createGraphics();
|
||||
g.drawImage(image, 0, 0, null);
|
||||
g.dispose();
|
||||
|
||||
bufferedImage.getRGB(0, 0, width, height, pixels, 0, width);
|
||||
}
|
||||
|
||||
setDnDIconImpl(nativePtr, width, height, offsetX, offsetY, pixels);
|
||||
}
|
||||
|
||||
public synchronized void destroy() {
|
||||
if (nativePtr != 0) {
|
||||
destroyImpl(nativePtr);
|
||||
|
||||
@@ -134,10 +134,11 @@ public abstract class WLDecoratedPeer extends WLWindowPeer {
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
final Dimension parentMinimumSize = super.getMinimumSize();
|
||||
final Dimension decorMinimumSize = getDecoration().getMinimumSize();
|
||||
var d = getDecoration();
|
||||
final Dimension decorMinimumSize = d != null ? d.getMinimumSize() : new Dimension(0, 0);
|
||||
final Dimension frameMinimumSize
|
||||
= (decorMinimumSize.getWidth() == 0 && decorMinimumSize.getHeight() == 0)
|
||||
? new Dimension(1, 1)
|
||||
? new Dimension(MINIMUM_WIDTH, MINIMUM_HEIGHT)
|
||||
: decorMinimumSize;
|
||||
return new Rectangle(parentMinimumSize)
|
||||
.union(new Rectangle(frameMinimumSize))
|
||||
|
||||
@@ -115,10 +115,16 @@ public class WLDragSourceContextPeer extends SunDragSourceContextPeer {
|
||||
|
||||
source.setDnDActions(waylandActions);
|
||||
|
||||
var dragImage = getDragImage();
|
||||
if (dragImage != null) {
|
||||
var dragImageOffset = getDragImageOffset();
|
||||
source.setDnDIcon(dragImage, dragImageOffset.x, dragImageOffset.y);
|
||||
}
|
||||
|
||||
long eventSerial = WLToolkit.getInputState().pointerButtonSerial();
|
||||
|
||||
var wlSurface = getComponentWlSurfacePtr();
|
||||
dataDevice.startDrag(source, wlSurface, 0, eventSerial);
|
||||
dataDevice.startDrag(source, wlSurface, eventSerial);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -199,7 +199,7 @@ public class WLSMSurfaceData extends SurfaceData implements WLSurfaceDataExt, WL
|
||||
private void countNewFrame() {
|
||||
// Called from the native code when this surface data has been sent to the Wayland server
|
||||
if (target instanceof Window window) {
|
||||
AWTAccessor.getWindowAccessor().bumpCounter(window, "java2d.native.frames");
|
||||
AWTAccessor.getWindowAccessor().incrementCounter(window, "java2d.native.frames");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ public class WLSMSurfaceData extends SurfaceData implements WLSurfaceDataExt, WL
|
||||
// the Wayland server, but that attempt was not successful. This can happen, for example,
|
||||
// when those attempts are too frequent.
|
||||
if (target instanceof Window window) {
|
||||
AWTAccessor.getWindowAccessor().bumpCounter(window, "java2d.native.framesDropped");
|
||||
AWTAccessor.getWindowAccessor().incrementCounter(window, "java2d.native.framesDropped");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -684,7 +684,7 @@ JNIEXPORT void JNICALL Java_sun_awt_wl_GtkFrameDecoration_nativePaintTitleBar
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_sun_awt_wl_GtkFrameDecoration_nativePrePaint(JNIEnv *env, jobject obj,
|
||||
jlong ptr, jint width) {
|
||||
jlong ptr, jint width, jint height) {
|
||||
assert (ptr != 0);
|
||||
GtkFrameDecorationDescr* decor = jlong_to_ptr(ptr);
|
||||
|
||||
@@ -714,6 +714,12 @@ JNIEXPORT void JNICALL Java_sun_awt_wl_GtkFrameDecoration_nativePrePaint(JNIEnv
|
||||
(*env)->SetIntField(env, obj, TitleBarHeightFID, pref_height);
|
||||
(*env)->SetIntField(env, obj, TitleBarMinWidthFID, min_width);
|
||||
|
||||
if (width < min_width || height < pref_height) {
|
||||
// Avoid gtk warnings in case of insufficient space
|
||||
p_gdk_threads_leave();
|
||||
return;
|
||||
}
|
||||
|
||||
GtkAllocation ha = {0, 0, width, pref_height};
|
||||
p_gtk_widget_size_allocate(decor->titlebar, &ha);
|
||||
|
||||
|
||||
@@ -72,6 +72,9 @@ struct DataSource
|
||||
struct wl_data_source *wlDataSource;
|
||||
struct zwp_primary_selection_source_v1 *zwpPrimarySelectionSource;
|
||||
};
|
||||
|
||||
struct wl_surface* dragIcon;
|
||||
struct wl_buffer* dragIconBuffer;
|
||||
};
|
||||
|
||||
// native part of WLDataOffer, remains alive until WLDataOffer.destroy() is called
|
||||
@@ -937,7 +940,7 @@ Java_sun_awt_wl_WLDataDevice_setSelectionImpl(JNIEnv *env,
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_wl_WLDataDevice_startDragImpl(JNIEnv *env, jclass clazz, jlong dataDeviceNativePtr,
|
||||
jlong dataSourceNativePtr, jlong wlSurfacePtr,
|
||||
jlong iconPtr, jlong serial)
|
||||
jlong serial)
|
||||
{
|
||||
struct DataDevice *dataDevice = jlong_to_ptr(dataDeviceNativePtr);
|
||||
assert(dataDevice != NULL);
|
||||
@@ -946,7 +949,10 @@ Java_sun_awt_wl_WLDataDevice_startDragImpl(JNIEnv *env, jclass clazz, jlong data
|
||||
assert(source != NULL);
|
||||
|
||||
wl_data_device_start_drag(dataDevice->wlDataDevice, source->wlDataSource, jlong_to_ptr(wlSurfacePtr),
|
||||
jlong_to_ptr(iconPtr), serial);
|
||||
source->dragIcon, serial);
|
||||
if (source->dragIcon != NULL) {
|
||||
wl_surface_commit(source->dragIcon);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
@@ -1045,6 +1051,14 @@ Java_sun_awt_wl_WLDataSource_destroyImpl(JNIEnv *env, jclass clazz, jlong native
|
||||
zwp_primary_selection_source_v1_destroy(source->zwpPrimarySelectionSource);
|
||||
}
|
||||
|
||||
if (source->dragIconBuffer) {
|
||||
wl_buffer_destroy(source->dragIconBuffer);
|
||||
}
|
||||
|
||||
if (source->dragIcon) {
|
||||
wl_surface_destroy(source->dragIcon);
|
||||
}
|
||||
|
||||
free(source);
|
||||
}
|
||||
|
||||
@@ -1058,6 +1072,65 @@ Java_sun_awt_wl_WLDataSource_setDnDActionsImpl(JNIEnv *env,
|
||||
DataSource_setDnDActions(source, actions);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_sun_awt_wl_WLDataSource_setDnDIconImpl
|
||||
(JNIEnv * env, jclass clazz, jlong nativePtr, jint width, jint height, jint offsetX, jint offsetY, jintArray pixels)
|
||||
{
|
||||
struct DataSource *source = jlong_to_ptr(nativePtr);
|
||||
|
||||
size_t pixelCount = (size_t)((*env)->GetArrayLength(env, pixels));
|
||||
size_t byteSize = pixelCount * 4U;
|
||||
if (byteSize >= INT32_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
jint *shmPixels = NULL;
|
||||
struct wl_shm_pool *pool = CreateShmPool(byteSize, "WLDataSource_DragIcon", (void**)&shmPixels, NULL);
|
||||
if (!pool) {
|
||||
return;
|
||||
}
|
||||
|
||||
(*env)->GetIntArrayRegion(env, pixels, 0, pixelCount, shmPixels);
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
// Wayland requires little-endian data
|
||||
for (size_t i = 0; i < pixelCount; i++) {
|
||||
uint32_t value = (uint32_t)shmPixels[i];
|
||||
shmPixels[i] = (jint)((value & 0xFFU) << 24 |
|
||||
(value & 0xFF00U) << 8 |
|
||||
(value & 0xFF0000U) >> 8 |
|
||||
(value & 0xFF000000U) >> 24 & 0xFFU);
|
||||
}
|
||||
#endif
|
||||
|
||||
source->dragIconBuffer = wl_shm_pool_create_buffer(pool, 0, width, height, width * 4, WL_SHM_FORMAT_ARGB8888);
|
||||
wl_shm_pool_destroy(pool);
|
||||
if (!source->dragIconBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
source->dragIcon = wl_compositor_create_surface(wl_compositor);
|
||||
if (!source->dragIcon) {
|
||||
wl_buffer_destroy(source->dragIconBuffer);
|
||||
source->dragIconBuffer = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
#if WL_SURFACE_OFFSET_SINCE_VERSION >= 5
|
||||
int wl_compositor_version = wl_compositor_get_version(wl_compositor);
|
||||
if (wl_compositor_version >= 5) {
|
||||
wl_surface_attach(source->dragIcon, source->dragIconBuffer, 0, 0);
|
||||
wl_surface_offset(source->dragIcon, offsetX, offsetY);
|
||||
} else {
|
||||
wl_surface_attach(source->dragIcon, source->dragIconBuffer, offsetX, offsetY);
|
||||
}
|
||||
#else
|
||||
wl_surface_attach(source->dragIcon, source->dragIconBuffer, offsetX, offsetY);
|
||||
#endif
|
||||
|
||||
wl_surface_damage_buffer(source->dragIcon, 0, 0, width, height);
|
||||
|
||||
// NOTE: we still need to commit the surface, this is done immediately after start_drag
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_wl_WLDataOffer_destroyImpl(JNIEnv *env, jclass clazz, jlong nativePtr)
|
||||
{
|
||||
|
||||
@@ -536,7 +536,12 @@ registry_global(void *data, struct wl_registry *wl_registry,
|
||||
if (strcmp(interface, wl_shm_interface.name) == 0) {
|
||||
wl_shm = wl_registry_bind( wl_registry, name, &wl_shm_interface, 1);
|
||||
} else if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||
wl_compositor = wl_registry_bind(wl_registry, name, &wl_compositor_interface, 4);
|
||||
#if WL_SURFACE_OFFSET_SINCE_VERSION >= 5
|
||||
uint32_t chosen_version = (version >= 5) ? 5 : 4;
|
||||
#else
|
||||
uint32_t chosen_version = 4;
|
||||
#endif
|
||||
wl_compositor = wl_registry_bind(wl_registry, name, &wl_compositor_interface, chosen_version);
|
||||
} else if (strcmp(interface, wl_subcompositor_interface.name) == 0) {
|
||||
wl_subcompositor = wl_registry_bind(wl_registry, name, &wl_subcompositor_interface, 1);
|
||||
} else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
|
||||
|
||||
@@ -831,11 +831,11 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
|
||||
if (sd.getPeer().getTarget() instanceof Window window) {
|
||||
switch (D3DRenderQueue.getFramePresentedStatus()) {
|
||||
case 1:
|
||||
AWTAccessor.getWindowAccessor().bumpCounter(window, "java2d.native.framesPresentRequested");
|
||||
AWTAccessor.getWindowAccessor().incrementCounter(window, "java2d.native.framesPresentRequested");
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
AWTAccessor.getWindowAccessor().bumpCounter(window, "java2d.native.framesPresentFailed");
|
||||
AWTAccessor.getWindowAccessor().incrementCounter(window, "java2d.native.framesPresentFailed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,9 +89,12 @@ vmTestbase/jit/misctests/JitBug1/JitBug1.java JBR-8801 linux-aarch64,windows-all
|
||||
vmTestbase/jit/misctests/Pi/Pi.java JBR-8854 linux-aarch64
|
||||
vmTestbase/jit/misctests/t5/t5.java JBR-8854 linux-aarch64
|
||||
vmTestbase/jit/misctests/putfield00802/putfield00802.java JBR-8801 linux-aarch64,windows-all
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi002/TestDescription.java JBR-8743 windows-all
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi003/TestDescription.java JBR-8743 windows-all
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi004/TestDescription.java JBR-8743,JBR-8744 windows-all
|
||||
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi001/Multi001.java JBR-8545 windows-aarch64,windows-x64
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi002/TestDescription.java JBR-8927,JBR-8545 windows-aarch64,windows-x64
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi003/TestDescription.java JBR-8927,JBR-8545 windows-aarch64,windows-x64
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi004/TestDescription.java JBR-8927,JBR-8545 windows-aarch64,windows-x64
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi005/TestDescription.java JBR-8927,JBR-8545 windows-aarch64,windows-x64
|
||||
|
||||
#############################################################################
|
||||
|
||||
|
||||
@@ -345,11 +345,10 @@ vmTestbase/vm/mlvm/meth/stress/compiler/deoptimize/Test.java#id1 8324756 generic
|
||||
|
||||
vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java 7199837 generic-all
|
||||
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi001/Multi001.java JBR-8545, windows-all
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi002/TestDescription.java JBR-8743 windows-all
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi003/TestDescription.java JBR-8743 windows-all
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi004/TestDescription.java JBR-8743 windows-all
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi005/TestDescription.java 8076494,JBR-8927 windows-x64,windows-aarch64
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi001/Multi001.java JBR-8545 windows-aarch64
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi002/TestDescription.java JBR-8927,JBR-8545 windows-aarch64
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi003/TestDescription.java JBR-8927,JBR-8545 windows-aarch64
|
||||
mTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Multi/Multi005/TestDescription.java JBR-8927,JBR-8545 windows-aarch64
|
||||
|
||||
vmTestbase/nsk/monitoring/ThreadMXBean/findMonitorDeadlockedThreads/find006/TestDescription.java 8310144 macosx-aarch64
|
||||
|
||||
|
||||
65
test/jdk/jb/javax/swing/wayland/WLFrameMinSize.java
Normal file
65
test/jdk/jb/javax/swing/wayland/WLFrameMinSize.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2025 JetBrains s.r.o.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Verifies that a small window does not generate GTK warnings in Wayland
|
||||
* @requires os.family == "linux"
|
||||
* @key headful
|
||||
* @library /test/lib
|
||||
* @run main WLFrameMinSize
|
||||
*/
|
||||
public class WLFrameMinSize {
|
||||
private static JFrame frame;
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length > 0 && args[0].equals("--test")) {
|
||||
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
frame = new JFrame("WLFrameMinSize");
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.getContentPane().add(new JLabel("a"));
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
Thread.sleep(2000);
|
||||
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
frame.dispose();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
|
||||
WLFrameMinSize.class.getName(),
|
||||
"--test");
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldNotContain("Gtk-WARNING");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ java/awt/Window/GrabSequence/GrabSequence.java 6848409,JBR-8584 macosx-all,linux
|
||||
javax/accessibility/JFileChooserAccessibleDescriptionTest.java JBR-5397,JBR-7379 macosx-all,windows-x64
|
||||
javax/accessibility/SlowPanelIteration/SlowPanelIteration.java JBR-870,JBR-5397 windows-x64,linux-x64,macosx-all
|
||||
javax/swing/event/FocusEventCauseTest.java JBR-7381 windows-x64
|
||||
javax/swing/JButton/4796987/bug4796987.java JBR-9345 windows-x64
|
||||
javax/swing/JButton/8151303/PressedIconTest.java JBR-5210,JBR-5510,JBR-5397 windows-all,linux-all,macosx-all
|
||||
javax/swing/JComboBox/4743225/bug4743225.java JBR-5210,JBR-5397 windows-all,macosx-all
|
||||
javax/swing/JComboBox/6559152/bug6559152.java JBR-5397,JBR-7382 macosx-all,windows-x64
|
||||
@@ -57,9 +58,10 @@ javax/swing/text/StyledEditorKit/4506788/bug4506788.java JBR-7386 windows-x64
|
||||
|
||||
jb/java/awt/CustomTitleBar/DialogNativeControlsTest.java JBR-9083 windows-x64
|
||||
jb/java/awt/Desktop/AboutHandlerTest.java nobug macosx-all,linux-all,windows-all
|
||||
jb/java/awt/Focus/FrameAfterPopup.java JBR-9161 windows-x64
|
||||
jb/java/awt/Focus/NewFrameAfterDialogTest.java JBR-7387 windows-x64
|
||||
jb/java/awt/Focus/ChainOfPopupsFocusTest.java JBR-8407 windows-x64
|
||||
jb/java/awt/Focus/FrameAfterPopup.java JBR-9161 windows-x64
|
||||
jb/java/awt/Focus/MaximizedCustomDecorationsTest.java JBR-9346 windows-x64
|
||||
jb/java/awt/Focus/NewFrameAfterDialogTest.java JBR-7387 windows-x64
|
||||
|
||||
# VoiceOver on MacOS
|
||||
java/awt/event/KeyEvent/ExtendedModifiersTest/ExtendedModifiersTest.java JBR-5397 macosx-all
|
||||
|
||||
@@ -115,12 +115,13 @@ java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java JBR-8960 w
|
||||
java/awt/Focus/ModalDialogInFocusEventTest.java JBR-7818 linux-6.14.0-1010-aws
|
||||
java/awt/Frame/GetGraphicsStressTest/GetGraphicsStressTest.java JBR-8542 windows-all timeout
|
||||
java/awt/Graphics2D/TextPerf.java JBR-8541 linux-all,windows-all
|
||||
java/awt/GridBagLayout/ComponentShortage.java JBR-9347 macosx-x64
|
||||
java/awt/KeyboardFocusmanager/TypeAhead/EnqueueWithDialogTest/EnqueueWithDialogTest.java JBR-7077 linux-all,windows-all
|
||||
java/awt/MenuItem/EnableTest.java JBR-8543 windows-all timeout
|
||||
java/awt/Robot/NonEmptyErrorStream.java JBR-6275 macosx-all
|
||||
java/awt/Robot/NonEmptyErrorStream.java 8340330,JBR-5510,JBR-6275,JBR-8299,JBR-9259 macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-15.6,macosx-all,linux-5.18.2-arch1-1,linux-aarch64,linux-6.15.8-100.fc41.x86_64
|
||||
|
||||
javax/swing/JWindow/ShapedAndTranslucentWindows/PerPixelTranslucentCanvas.java JBR-7404 macosx-all
|
||||
javax/swing/plaf/synth/7158712/bug7158712.java 8322653,JBR-9061 macosx-all,linux-6.8.0-1033-aws
|
||||
javax/swing/plaf/synth/7158712/bug7158712.java 8322653,JBR-9061 macosx-all,linux-6.8.0-1033-aws,linux-6.8.0-1036-aws
|
||||
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-5952,8340330,JBR-6274 windows-all,macosx-15.3,macosx-15.3.1,macosx-15.3.2,macosx-15.4,macosx-15.4.1,macosx-15.5,macosx-all
|
||||
|
||||
jb/build/ResolveSymbolsTest/ResolveSymbolsRealEnv.java JBR-8544 linux-all
|
||||
|
||||
@@ -24,6 +24,7 @@ java/awt/font/TextLayout/VisibleAdvance.java JBR-8766 linux-all
|
||||
java/awt/FontMetrics/ExtremeFontSizeTest.java JBR-7823 linux-all
|
||||
java/awt/Graphics2D/DrawString/IgnoredWhitespaceTest.java JBR-9086 linux-all
|
||||
java/awt/Graphics2D/DrawString/RotTransText.java JBR-8767 linux-all
|
||||
java/awt/Graphics/NativeWin32Clear.java JBR-8689 linux-x64
|
||||
java/awt/Graphics/XORPaint.java#id2 JBR-7373 linux-x64
|
||||
java/awt/image/DrawImage/SimpleManagedImage.java JBR-8769 linux-all
|
||||
java/awt/image/DrawImage/SimpleUnmanagedImage.java JBR-8769 linux-all
|
||||
|
||||
@@ -134,6 +134,7 @@ java/awt/Focus/FocusTraversalPolicy/ButtonGroupLayoutTraversal/ButtonGroupLayout
|
||||
java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-all
|
||||
java/awt/Focus/IconifiedFrameFocusChangeTest/IconifiedFrameFocusChangeTest.java 6849364 generic-all
|
||||
java/awt/Focus/InactiveFocusRace.java 8023263,JBR-8586 linux-all,windows-x64
|
||||
java/awt/Focus/InputVerifierTest3/InputVerifierTest3.java JBR-7311 linux-6.8.0-1036-aws
|
||||
java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusToFrontTest.java 6848406 generic-all
|
||||
java/awt/Focus/AutoRequestFocusTest/AutoRequestFocusSetVisibleTest.java 6848407 generic-all
|
||||
java/awt/Focus/LabelScrollBarFocus.java JBR-8027 linux-all
|
||||
@@ -353,14 +354,9 @@ java/awt/Window/Grab/GrabTest.java 8253184 windows-all
|
||||
java/awt/Window/GrabSequence/GrabSequence.java 6848409 macosx-all,linux-all
|
||||
java/awt/Window/LocationAtScreenCorner/LocationAtScreenCorner.java 8203371 linux-all
|
||||
java/awt/FontClass/FontAccess.java JBR-5225 windows-all
|
||||
java/awt/font/ComplexEmoji.java JBR-5009 linux-aarch64
|
||||
java/awt/font/Emoji/ComplexEmoji.java JBR-8282 generic-all
|
||||
java/awt/font/Emoji/EmojiVariation.java JBR-8716 linux-5.18.2-arch1-1
|
||||
java/awt/font/EmojiVariation.java JBR-5009,JBR-5510 linux-aarch64,linux-5.18.2-arch1-1
|
||||
java/awt/font/FontScaling/StretchedFontTest.java JBR-6225 macosx-all
|
||||
java/awt/font/GlyphVector/LayoutCompatTest.java JBR-8437 linux-aarch64
|
||||
java/awt/font/JNICheck/JNICheck.sh JBR-5011 linux-all
|
||||
java/awt/font/OutlineTextRendererEmoji.java JBR-5009 linux-aarch64
|
||||
java/awt/font/TextLayout/ArabicDiacriticTest.java JBR-6760 linux-i386
|
||||
java/awt/font/TextLayout/DecorationBoundsTest.java JBR-6760 linux-i386
|
||||
java/awt/font/TextLayout/FormatCharAdvanceTest.java JBR-8289 macosx-all
|
||||
@@ -397,7 +393,7 @@ sun/java2d/loops/XORClearRect.java JBR-8718 linux-5.18.2-arch1-1
|
||||
java/awt/Graphics/GDIResourceExhaustionTest.java JBR-8719 linux-5.18.2-arch1-1
|
||||
java/awt/Graphics/NativeWin32Clear.java JBR-8689 linux-aarch64,linux-5.18.2-arch1-1
|
||||
java/awt/Graphics/XORPaint.java#id1 JBR-8642 macosx-aarch64
|
||||
java/awt/Graphics/XORPaint.java#id2 JBR-5510 linux-5.18.2-arch1-1
|
||||
java/awt/Graphics/XORPaint.java#id2 JBR-9348 linux-6.15.8-100.fc41.x86_64
|
||||
java/awt/Graphics2D/CopyAreaOOB.java JBR-5354,JBR-9206 macosx-all,windows-all,linux-5.18.2-arch1-1,linux-6.15.8-100.fc41.x86_64
|
||||
java/awt/Graphics2D/DrawString/DisposerTest.java JBR-5010,JBR-5510 linux-aarch64,linux-5.18.2-arch1-1
|
||||
java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java 8266283 generic-all
|
||||
@@ -903,6 +899,7 @@ java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java 8144003,JBR-921
|
||||
java/nio/channels/DatagramChannel/Promiscuous.java 8144003,JBR-9218 macosx-all,linux-6.15.8-100.fc41.x86_64
|
||||
java/nio/channels/DatagramChannel/PromiscuousIPv6.java JBR-8828,JBR-9218 macosx-x64,linux-6.15.8-100.fc41.x86_64
|
||||
java/nio/channels/DatagramChannel/Unref.java 8233437 generic-all
|
||||
java/nio/channels/FileChannel/LargeGatheringWrite.java JBR-9316 linux-6.15.8-100.fc41.x86_64
|
||||
java/nio/channels/Selector/LotsOfInterrupts.java#virtual JBR-8940 windows-aarch64
|
||||
java/nio/channels/Selector/Wakeup.java 6963118 windows-all
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ java/awt/dnd/DnDAWTLockTest.java JBR-8745 linux-all
|
||||
java/awt/dnd/DragOverDropTargetPerformanceTest.java JBR-5799 windows-all
|
||||
java/awt/dnd/DragSourceGCrashTest.java JBR-8745 linux-all
|
||||
java/awt/dnd/InterJVMGetDropSuccessTest/InterJVMGetDropSuccessTest.java JBR-8745 linux-all
|
||||
java/awt/dnd/InterJVMLinkTest.java JBR-9255 linux-6.15.8-100.fc41.x86_64
|
||||
java/awt/Dialog/ChoiceModalDialogTest.java JBR-8724 windows-all
|
||||
java/awt/dnd/MozillaDnDTest.java JBR-6442 linux-all
|
||||
java/awt/event/ComponentEvent/TextComponentTextEventTest.java JBR-6287 windows-all
|
||||
@@ -67,7 +68,7 @@ javax/swing/JButton/bug4490179.java JBR-8925 windows-all
|
||||
javax/swing/JFileChooser/JFileChooserSetLocationTest.java JBR-8098 linux-all,windows-all
|
||||
javax/swing/JInternalFrame/4202966/IntFrameCoord.java JBR-9006 window-all
|
||||
javax/swing/JMenu/bug4342646.java JBR-8727 linux-all,windows-all
|
||||
javax/swing/JPopupMenu/6580930/bug6580930.java JBR-5071 linux-6.8.0-1033-aws
|
||||
javax/swing/JPopupMenu/6580930/bug6580930.java JBR-5071 linux-6.8.0-1033-aws,linux-6.8.0-1036-aws,linux-6.15.8-100.fc41.x86_64
|
||||
javax/swing/JTable/JTableRightOrientationTest.java JBR-8102 linux-all,windows-all
|
||||
javax/swing/text/ParagraphView/6364882/bug6364882.java JBR-8747 linux-all
|
||||
javax/swing/plaf/basic/BasicGraphicsUtils/8132119/bug8132119.java JBR-8357 linux-all
|
||||
@@ -86,6 +87,7 @@ jdk/editpad/EditPadTest.java
|
||||
|
||||
sanity/client/SwingSet/src/ColorChooserDemoTest.java JBR-8354,JBR-8933 linux-all,windows-aarch64,windows-10.0
|
||||
sanity/client/SwingSet/src/EditorPaneDemoTest.java JBR-5510,JBR-6285 linux-5.18.2-arch1-1,linux-all
|
||||
sanity/client/SwingSet/src/GridBagLayoutDemoTest.java JBR-6285 linux-all
|
||||
sanity/client/SwingSet/src/InternalFrameDemoTest.java JBR-6685 linux-all
|
||||
sanity/client/SwingSet/src/ToolTipDemoTest.java 8293001,JBR-6293 linux-all,windows-all
|
||||
sun/java2d/GdiRendering/ClipShapeRendering.java JBR-5204 linux-all,macosx-all,windows-all
|
||||
@@ -110,7 +112,7 @@ java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java nobug generic-all
|
||||
java/awt/Graphics/CopyScaledArea/CopyScaledAreaTest.java nobug generic-all
|
||||
java/awt/Graphics/DrawOvalTest.java nobug generic-all
|
||||
java/awt/Graphics/XORPaint.java#id1 JBR-8642,nobug macosx-aarch64,windows-all
|
||||
java/awt/Graphics/XORPaint.java#id2 JBR-5510,nobug linux-5.18.2-arch1-1,windows-all
|
||||
java/awt/Graphics/XORPaint.java#id2 nobug generic-all
|
||||
java/awt/Graphics/XORPaint.java#id3 nobug windows-all
|
||||
java/awt/Graphics/XORPaint.java#id4 nobug windows-all
|
||||
java/awt/Graphics/XORPaint.java#id5 nobug windows-all
|
||||
@@ -177,6 +179,7 @@ javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id0 JBR-7965,JBR-8345 w
|
||||
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id2 JBR-8345 linux-all
|
||||
javax/swing/JButton/TestGlyphBreak.java nobug generic-all
|
||||
javax/swing/JComboBox/6559152/bug6559152.java JBR-8964 windows-all
|
||||
javax/swing/JComboBox/8033069/bug8033069NoScrollBar.java JBR-9342 windows-x64
|
||||
javax/swing/JComboBox/DisabledComboBoxFontTestAuto.java nobug generic-all
|
||||
javax/swing/JFrame/8175301/ScaledFrameBackgroundTest.java nobug generic-all
|
||||
javax/swing/JInternalFrame/8069348/bug8069348.java nobug generic-all
|
||||
|
||||
@@ -22,9 +22,13 @@ java/awt/Toolkit/ToolkitPropertyTest/ToolkitPropertyTest_Disable.java JBR-9100 l
|
||||
javax/swing/AbstractButton/bug4147740.java JBR-9100 linux-all
|
||||
javax/swing/AbstractButton/bug4246045.java JBR-9100 linux-all
|
||||
javax/swing/border/Test6981576.java JBR-9100 linux-all
|
||||
java/awt/image/DrawImage/BlitRotateClippedArea.java JBR-9026 linux-all
|
||||
java/awt/image/DrawImage/EABlitTest.java JBR-9027 linux-all
|
||||
javax/swing/GraphicsConfigNotifier/StalePreferredSize.java JBR-9031 linux-all
|
||||
javax/swing/GraphicsConfigNotifier/TestMultiScreenGConfigNotify.java JBR-8266 linux-x64
|
||||
javax/swing/GroupLayout/8079640/bug8079640.java JBR-9100 linux-all
|
||||
javax/swing/JButton/JButtonPaintNPE/JButtonPaintNPE.java JBR-9100 linux-all
|
||||
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id0 JBR-7928,JBR-9341 linux-6.8.0-1036-aws,linux-6.14.9-arch1-1
|
||||
javax/swing/JColorChooser/Test4177735.java JBR-9100 linux-all
|
||||
javax/swing/JComboBox/8019180/Test8019180.java JBR-9100 linux-all
|
||||
javax/swing/JComboBox/bug4276920.java JBR-9100 linux-all
|
||||
@@ -39,6 +43,7 @@ javax/swing/JFileChooser/6489130/bug6489130.java JBR-9100 linux-all
|
||||
javax/swing/JFileChooser/DeserializedJFileChooser/DeserializedJFileChooserTest.java JBR-9100 linux-all
|
||||
javax/swing/JFileChooser/FileSizeCheck.java JBR-9100 linux-all
|
||||
javax/swing/JFileChooser/FileViewNPETest.java JBR-9100 linux-all
|
||||
javax/swing/JFormattedTextField/bug4741926.java JBR-9321 linux-6.14.9-arch1-1
|
||||
javax/swing/JFormattedTextField/TestSelectedTextBackgroundColor.java JBR-9100 linux-all
|
||||
javax/swing/JFrame/AlwaysOnTop/AlwaysOnTopImeTest.java JBR-9100 linux-all
|
||||
javax/swing/JFrame/HangNonVolatileBuffer/HangNonVolatileBuffer.java JBR-9100 linux-all
|
||||
@@ -48,7 +53,7 @@ javax/swing/JLayer/6824395/bug6824395.java JBR-9100 linux-all
|
||||
javax/swing/JLayer/8041982/bug8041982.java JBR-9100 linux-all
|
||||
javax/swing/JMenu/8178430/LabelDotTest.java JBR-9100 linux-all
|
||||
javax/swing/JPanel/bug4907772.java JBR-9100 linux-all
|
||||
javax/swing/JPasswordField/TestSelectedTextBackgroundColor.java JBR-9100 linux-all
|
||||
javax/swing/JPasswordField/TestSelectedTextBackgroundColor.java JBR-9277 linux-6.14.9-arch1-1
|
||||
javax/swing/JProgressBar/8161664/ProgressBarMemoryLeakTest.java JBR-9100 linux-all
|
||||
javax/swing/JProgressBar/TestJProgressBarHighlightColor.java JBR-9100 linux-all
|
||||
javax/swing/JScrollPane/bug8044371.java JBR-9100 linux-all
|
||||
@@ -57,7 +62,7 @@ javax/swing/JSlider/TestJSliderRendering.java JBR-9100 linux-all
|
||||
javax/swing/JSpinner/8008657/bug8008657.java JBR-9100 linux-all
|
||||
javax/swing/JSpinner/bug4656590.java JBR-9100 linux-all
|
||||
javax/swing/JSpinner/bug4680204.java JBR-9100 linux-all
|
||||
javax/swing/JSpinner/TestSelectedTextBackgroundColor.java JBR-9100 linux-all
|
||||
javax/swing/JSpinner/TestSelectedTextBackgroundColor.java JBR-9277 linux-6.14.9-arch1-1
|
||||
javax/swing/JSplitPane/4816114/bug4816114.java JBR-9100 linux-all
|
||||
javax/swing/JSplitPane/JSplitPaneTestNegDivSize.java JBR-9100 linux-all
|
||||
javax/swing/JTabbedPane/7170310/bug7170310.java JBR-9100 linux-all
|
||||
@@ -78,6 +83,7 @@ javax/swing/JTextPane/JTextPaneDocumentWrapping.java JBR-9100 linux-all
|
||||
javax/swing/JTextPane/TestJTextPaneBackgroundColor.java JBR-9100 linux-all
|
||||
javax/swing/JTree/8041705/DefaultTreeCellRendererBorderTest.java JBR-9100 linux-all
|
||||
javax/swing/JViewport/7107099/bug7107099.java JBR-9100 linux-all
|
||||
javax/swing/InputVerifier/VerifyTarget/VerifyTargetTest.java JBR-9320 linux-6.14.9-arch1-1
|
||||
javax/swing/LookAndFeel/8145547/DemandGTK.java JBR-9100 linux-all
|
||||
javax/swing/LookAndFeel/8145547/DemandGTK3.sh JBR-9100 linux-all
|
||||
javax/swing/plaf/basic/6866751/bug6866751.java JBR-9100 linux-all
|
||||
|
||||
@@ -1,2 +1,9 @@
|
||||
javax/swing/JFileChooser/6520101/bug6520101.java JBR-8434 linux-all
|
||||
javax/swing/JMenu/bug4342646.java JBR-8727 linux-all
|
||||
javax/swing/JTable/JTableRightOrientationTest.java JBR-8102 linux-all
|
||||
javax/swing/plaf/basic/BasicGraphicsUtils/8132119/bug8132119.java JBR-8357 linux-all
|
||||
javax/swing/plaf/basic/BasicGraphicsUtils/8132119/bug8132119.java JBR-8357 linux-all
|
||||
|
||||
jb/java/awt/wayland/vulkan/ImageTransformTest.java JBR-8434 linux-all
|
||||
jb/java/awt/wayland/vulkan/RobotGetPixelsTest.java JBR-8434 linux-all
|
||||
jb/java/awt/wayland/vulkan/RobotGetPixelTest.java JBR-8434 linux-all
|
||||
jb/java/awt/wayland/vulkan/VulkanMaskFillTest.java JBR-8434 linux-all
|
||||
@@ -7,18 +7,18 @@ javax/swing/AbstractDocument/bug4549069.java JBR-8267 linux-6.14.0-1010-aws
|
||||
javax/swing/JComponent/6989617/bug6989617.java JBR-8796 linux-6.14.0-1010-aws
|
||||
javax/swing/JDesktopPane/TestDesktopManagerNPE.java JBR-8449 linux-x64
|
||||
javax/swing/GraphicsConfigNotifier/TestMultiScreenGConfigNotify.java JBR-8266 linux-x64
|
||||
javax/swing/InputVerifier/VerifyTarget/VerifyTargetTest.java JBR-7520 linux-all
|
||||
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id0 JBR-7928,JBR-8265 linux-all
|
||||
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id2 JBR-8265 linux-all
|
||||
javax/swing/InputVerifier/VerifyTarget/VerifyTargetTest.java JBR-7520,JBR-9320 linux-6.8.0-1036-aws,linux-6.14.9-arch1-1
|
||||
javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java#id0 JBR-7928,JBR-9341 linux-6.8.0-1036-aws,linux-6.14.9-arch1-1
|
||||
javax/swing/JEditorPane/bug4325606.java JBR-8267 linux-aarch64
|
||||
javax/swing/JEditorPane/JEditorPaneFontFallback.java JBR-8305 linux-all
|
||||
javax/swing/JFormattedTextField/bug4741926.java JBR-7530 linux-all
|
||||
javax/swing/JFormattedTextField/bug4741926.java JBR-7530,JBR-9321 linux-all,linux-6.14.9-arch1-1
|
||||
javax/swing/JFormattedTextField/TestSelectedTextBackgroundColor.java JBR-8790 linux-all
|
||||
javax/swing/JInternalFrame/bug5009724.java JBR-7087 linux-all
|
||||
javax/swing/JMenu/JMenuSelectedColorTest.java JBR-8551 linux-all
|
||||
javax/swing/JPasswordField/TestSelectedTextBackgroundColor.java JBR-9277 linux-6.14.9-arch1-1
|
||||
javax/swing/JPopupMenu/7156657/bug7156657.java JBR-8210 linux-all
|
||||
javax/swing/JRadioButton/bug4823809.java JBR-7774 linux-all
|
||||
javax/swing/JSlider/TestJSliderRendering.java JBR-8551 linux-all
|
||||
javax/swing/JSpinner/TestSelectedTextBackgroundColor.java JBR-9277 linux-6.14.9-arch1-1
|
||||
javax/swing/JTabbedPane/6495408/bug6495408.java JBR-8267 linux-aarch64
|
||||
javax/swing/JToolTip/TestTooltipBackgroundColor.java JBR-8551 linux-all
|
||||
javax/swing/LookAndFeel/8145547/DemandGTK3.sh JBR-8274 linux-all
|
||||
@@ -27,4 +27,4 @@ javax/swing/text/ParagraphView/6364882/bug6364882.java JBR-8324 linux-all
|
||||
javax/swing/UI/UnninstallUIMemoryLeaks/UnninstallUIMemoryLeaks.java JBR-8304 linux-all
|
||||
|
||||
jb/java/awt/wayland/VulkanMaskFillTest.java JBR-8446 linux-6.8.0-1017-raspi
|
||||
jb/javax/swing/Popup/WLPopupMoves.java JBR-8296 linux-all
|
||||
jb/javax/swing/wayland/WLPopupMoves.java JBR-8296 linux-all
|
||||
@@ -1,2 +1,4 @@
|
||||
javax/swing/JFileChooser/6520101/bug6520101.java JBR-7140 linux-all
|
||||
javax/swing/JMenu/bug4342646.java JBR-8727 linux-all
|
||||
javax/swing/JTable/JTableRightOrientationTest.java JBR-8102 linux-all
|
||||
javax/swing/plaf/basic/BasicGraphicsUtils/8132119/bug8132119.java JBR-8357 linux-all
|
||||
Reference in New Issue
Block a user