Compare commits

...

8 Commits

21 changed files with 907 additions and 275 deletions

View File

@@ -102,6 +102,12 @@ else
WITH_BUNDLED_FREETYPE=""
fi
if [ "$bundle_type" == "vk" ]; then
WITH_VULKAN="--with-vulkan"
else
WITH_VULKAN=""
fi
REPRODUCIBLE_BUILD_OPTS="--with-source-date=$SOURCE_DATE_EPOCH
--with-hotspot-build-time=$BUILD_TIME
--with-copyright-year=$COPYRIGHT_YEAR

View File

@@ -35,7 +35,7 @@ function do_configure {
--with-version-opt=b"$build_number" \
--with-boot-jdk="$BOOT_JDK" \
--enable-cds=yes \
--with-vulkan \
$WITH_VULKAN \
$DISABLE_WARNINGS_AS_ERRORS \
$STATIC_CONF_ARGS \
$REPRODUCIBLE_BUILD_OPTS \
@@ -113,6 +113,11 @@ case "$bundle_type" in
jbr_name_postfix="_${bundle_type}"
do_maketest=1
;;
"vk")
do_reset_changes=1
jbr_name_postfix="_${bundle_type}"
do_maketest=1
;;
"nomod" | "")
bundle_type=""
;;
@@ -141,7 +146,7 @@ JBRSDK_BUNDLE=jbrsdk
echo Fixing permissions
chmod -R a+r $JSDK
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "vk" ] || [ "$bundle_type" == "fd" ]; then
git apply -p0 < jb/project/tools/patches/add_jcef_module_aarch64.patch || do_exit $?
update_jsdk_mods $JSDK $JCEF_PATH/jmods $JSDK/jmods $JSDK_MODS_DIR || do_exit $?
cp $JCEF_PATH/jmods/* $JSDK_MODS_DIR # $JSDK/jmods is not changed
@@ -154,7 +159,7 @@ create_image_bundle "jbr${jbr_name_postfix}" "jbr" $JSDK_MODS_DIR "$modules" ||
# create sdk image bundle
modules=$(cat $JSDK/release | grep MODULES | sed s/MODULES=//g | sed s/' '/','/g | sed s/\"//g | sed s/\\n//g) || do_exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "vk" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
fi
create_image_bundle "$JBRSDK_BUNDLE${jbr_name_postfix}" $JBRSDK_BUNDLE $JSDK_MODS_DIR "$modules" || do_exit $?

View File

@@ -42,7 +42,7 @@ function do_configure {
--with-version-opt=b"$build_number" \
--with-boot-jdk="$BOOT_JDK" \
--enable-cds=yes \
--with-vulkan \
$WITH_VULKAN \
$LINUX_TARGET \
$DISABLE_WARNINGS_AS_ERRORS \
$STATIC_CONF_ARGS \
@@ -121,6 +121,11 @@ case "$bundle_type" in
jbr_name_postfix="_${bundle_type}"
do_maketest=1
;;
"vk")
do_reset_changes=1
jbr_name_postfix="_${bundle_type}"
do_maketest=1
;;
"nomod" | "")
bundle_type=""
;;
@@ -149,7 +154,7 @@ JBRSDK_BUNDLE=jbrsdk
echo Fixing permissions
chmod -R a+r $JSDK
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "vk" ] || [ "$bundle_type" == "fd" ]; then
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
update_jsdk_mods $JSDK $JCEF_PATH/jmods $JSDK/jmods $JSDK_MODS_DIR || do_exit $?
cp $JCEF_PATH/jmods/* $JSDK_MODS_DIR # $JSDK/jmods is not changed
@@ -162,7 +167,7 @@ create_image_bundle "jbr${jbr_name_postfix}" "jbr" $JSDK_MODS_DIR "$modules" ||
# create sdk image bundle
modules=$(cat $JSDK/release | grep MODULES | sed s/MODULES=//g | sed s/' '/','/g | sed s/\"//g | sed s/\\n//g) || do_exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "vk" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
fi
create_image_bundle "$JBRSDK_BUNDLE${jbr_name_postfix}" $JBRSDK_BUNDLE $JSDK_MODS_DIR "$modules" || do_exit $?

View File

@@ -92,7 +92,7 @@ WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=linux-x86-server-release
case "$bundle_type" in
"jcef")
"jcef" | "vk")
echo "not implemented" && do_exit 1
;;
"nomod" | "")
@@ -119,7 +119,7 @@ JBRSDK_BUNDLE=jbrsdk
echo Fixing permissions
chmod -R a+r $JSDK
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "vk" ]; then
jbr_name_postfix="_${bundle_type}"
else
jbr_name_postfix=""

View File

@@ -7,7 +7,7 @@
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<false/>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>

View File

@@ -55,8 +55,10 @@ done
log "Signing jmod files"
JMODS_DIR="$APPLICATION_PATH/Contents/Home/jmods"
JMOD_EXE="$APPLICATION_PATH/Contents/Home/bin/jmod"
JMOD_EXE="$BOOT_JDK/bin/jmod"
if [ -d "$JMODS_DIR" ]; then
log "processing jmods"
for jmod_file in "$JMODS_DIR"/*.jmod; do
log "Processing $jmod_file"
@@ -64,16 +66,16 @@ if [ -d "$JMODS_DIR" ]; then
rm -rf "$TMP_DIR"
mkdir "$TMP_DIR"
log "Unzipping $jmod_file"
log "Unzipping $jmod_file"
$JMOD_EXE extract --dir "$TMP_DIR" "$jmod_file" >/dev/null
log "Removing $jmod_file"
rm -f "$jmod_file"
log "Signing dylibs in $TMP_DIR"
find "$TMP_DIR" \
-type f \( -name "*.dylib" -o -name "*.so" -o -perm +111 -o -name jarsigner -o -name jdeps -o -name jpackageapplauncher -o -name jspawnhelper -o -name jar -o -name javap -o -name jdeprscan -o -name jfr -o -name rmiregistry -o -name java -o -name jhsdb -o -name jstatd -o -name jstatd -o -name jpackage -o -name keytool -o -name jmod -o -name jlink -o -name jimage -o -name jstack -o -name jcmd -o -name jps -o -name jmap -o -name jstat -o -name jinfo -o -name jshell -o -name jwebserver -o -name javac -o -name serialver -o -name jrunscript -o -name jdb -o -name jconsole -o -name javadoc \) \
-exec sh -c '"$1" --timestamp -v -s "$2" --options=runtime --force --entitlements "$3" "$4" || exit 1' sh "$SIGN_UTILITY" "$JB_DEVELOPER_CERT" "$SCRIPT_DIR/entitlements.xml" {} \;
log "Removing $jmod_file"
rm -f "$jmod_file"
cmd="$JMOD_EXE create --class-path $TMP_DIR/classes"
# Check each directory and add to the command if it exists
@@ -84,6 +86,8 @@ if [ -d "$JMODS_DIR" ]; then
[ -d "$TMP_DIR/legal" ] && cmd="$cmd --legal-notices $TMP_DIR/legal"
[ -d "$TMP_DIR/man" ] && cmd="$cmd --man-pages $TMP_DIR/man"
log "Creating jmod file"
log "$cmd"
# Add the output file
cmd="$cmd $jmod_file"
@@ -93,6 +97,41 @@ if [ -d "$JMODS_DIR" ]; then
log "Removing $TMP_DIR"
rm -rf "$TMP_DIR"
done
log "Repack java.base.jmod with new hashes of modules"
hash_modules=$($JMOD_EXE describe $JMODS_DIR/java.base.jmod | grep hashes | awk '{print $2}' | tr '\n' '|' | sed s/\|$//) || exit $?
TMP_DIR="$JMODS_DIR/tmp"
rm -rf "$TMP_DIR"
mkdir "$TMP_DIR"
jmod_file="$JMODS_DIR/java.base.jmod"
log "Unzipping $jmod_file"
$JMOD_EXE extract --dir "$TMP_DIR" "$jmod_file" >/dev/null
log "Removing java.base.jmod"
rm -f "$jmod_file"
cmd="$JMOD_EXE create --class-path $TMP_DIR/classes --hash-modules \"$hash_modules\" --module-path $JMODS_DIR"
# Check each directory and add to the command if it exists
[ -d "$TMP_DIR/bin" ] && cmd="$cmd --cmds $TMP_DIR/bin"
[ -d "$TMP_DIR/conf" ] && cmd="$cmd --config $TMP_DIR/conf"
[ -d "$TMP_DIR/lib" ] && cmd="$cmd --libs $TMP_DIR/lib"
[ -d "$TMP_DIR/include" ] && cmd="$cmd --header-files $TMP_DIR/include"
[ -d "$TMP_DIR/legal" ] && cmd="$cmd --legal-notices $TMP_DIR/legal"
[ -d "$TMP_DIR/man" ] && cmd="$cmd --man-pages $TMP_DIR/man"
log "Creating jmod file"
log "$cmd"
# Add the output file
cmd="$cmd $jmod_file"
# Execute the command
eval $cmd
log "Removing $TMP_DIR"
rm -rf "$TMP_DIR"
else
echo "Directory '$JMODS_DIR' does not exist. Skipping signing of jmod files."
fi

View File

@@ -863,7 +863,7 @@ MTLBlitLoops_CopyArea(JNIEnv *env,
MTLCommandBufferWrapper * cbwrapper =
[mtlc pullCommandBufferWrapper];
id<MTLCommandBuffer> commandbuf = [cbwrapper getCommandBuffer];
[commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) {
[commandbuf addCompletedHandler:^(id <MTLCommandBuffer> cb) {
[cbwrapper release];
}];
[commandbuf commit];

View File

@@ -90,7 +90,7 @@
@property (strong) id<MTLCommandQueue> blitCommandQueue;
@property (strong) id<MTLBuffer> vertexBuffer;
@property (readonly) NSMutableDictionary<NSNumber*, NSValue*>* displayLinks;
@property (readonly) NSMutableDictionary<NSNumber*, NSValue*>* displayLinkStates;
@property (readonly) EncoderManager * encoderManager;
@property (readonly) MTLSamplerManager * samplerManager;
@@ -111,10 +111,11 @@
+ (NSMutableDictionary*) contextStore;
+ (MTLContext*) createContextWithDeviceIfAbsent:(jint)displayID shadersLib:(NSString*)mtlShadersLib;
- (id)initWithDevice:(id<MTLDevice>)device display:(jint) displayID shadersLib:(NSString*)mtlShadersLib;
- (id)initWithDevice:(id<MTLDevice>)device shadersLib:(NSString*)mtlShadersLib;
- (void)dealloc;
- (void)handleDisplayLink:(BOOL)enabled display:(jint)display source:(const char*)src;
- (NSArray<NSNumber*>*)getDisplayLinkDisplayIds;
- (void)handleDisplayLink:(BOOL)enabled displayID:(jint)displayID source:(const char*)src;
- (void)createDisplayLinkIfAbsent: (jint)displayID;
/**
@@ -253,6 +254,7 @@
- (void)commitCommandBuffer:(BOOL)waitUntilCompleted display:(BOOL)updateDisplay;
- (void)startRedraw:(MTLLayer*)layer;
- (void)stopRedraw:(MTLLayer*)layer;
- (void)stopRedraw:(jint)displayID layer:(MTLLayer*)layer;
- (void)haltRedraw;
@end

View File

@@ -39,9 +39,13 @@
// scenarios with multiple subsequent updates.
#define KEEP_ALIVE_COUNT 4
// Min interval between 2 display link callbacks (Main thread may be busy)
// ~ 2ms (shorter than best monitor frame rate = 500 hz)
#define KEEP_ALIVE_MIN_INTERVAL 2.0 / 1000.0
#define TO_MS(x) (1000.0 * (x))
#define TO_FPS(x) (1.0 / (x))
// Min interval(s) between 2 display link callbacks as the appkit (Main)
// thread may be 'blocked' (waiting), then callbacks will be invoked in batches.
// ~ 0.250ms (shorter than best monitor frame rate = 4 khz)
#define KEEP_ALIVE_MIN_INTERVAL (0.250 / 1000.0)
// Amount of blit operations per update to make sure that everything is
// rendered into the window drawable. It does not slow things down as we
@@ -53,20 +57,36 @@ extern BOOL isDisplaySyncEnabled();
extern BOOL MTLLayer_isExtraRedrawEnabled();
extern int getBPPFromModeString(CFStringRef mode);
#define STATS_CVLINK 0
#define STATS_CVLINK 0
#define TRACE_CVLINK 0
#define TRACE_DISPLAY 0
#define TRACE_PWM_NOTIF 0
#define CHECK_CVLINK(op, source, cmd) \
{ \
CVReturn ret = (CVReturn) (cmd); \
if (ret != kCVReturnSuccess) { \
J2dTraceImpl(J2D_TRACE_ERROR, JNI_TRUE, "CVDisplayLink[%s - %s] Error: %d", \
op, (source != nil) ? source : "", ret); \
} \
#define TRACE_CVLINK 0
#define TRACE_CVLINK_WARN 0
#define TRACE_CVLINK_DEBUG 0
#define TRACE_DISPLAY 0
#define CHECK_CVLINK(op, source, dl, cmd) \
{ \
CVReturn ret = (CVReturn) (cmd); \
if (ret != kCVReturnSuccess) { \
J2dTraceImpl(J2D_TRACE_ERROR, JNI_TRUE, "CVDisplayLink[%s - %s][%p] Error: %d", \
op, (source != nil) ? source : "", dl, ret); \
} else if (TRACE_CVLINK) { \
J2dTraceImpl(J2D_TRACE_VERBOSE, JNI_TRUE, "CVDisplayLink[%s - %s][%p]: OK", \
op, (source != nil) ? source : "", dl); \
} \
}
boolean_t mtlc_IsDisplayReallyActive(CGDirectDisplayID displayID) {
return CGDisplayIsActive(displayID) & !CGDisplayIsAsleep(displayID) && CGDisplayIsOnline(displayID);
}
/* 60 fps typically => exponential smoothing on 0.5s */
static const NSTimeInterval EXP_AVG_WEIGHT = (1.0 / 30.0);
static const NSTimeInterval EXP_INV_WEIGHT = (1.0 - EXP_AVG_WEIGHT);
static struct TxtVertex verts[PGRAM_VERTEX_COUNT] = {
{{-1.0, 1.0}, {0.0, 0.0}},
{{1.0, 1.0}, {1.0, 0.0}},
@@ -80,7 +100,15 @@ typedef struct {
jint displayID;
CVDisplayLinkRef displayLink;
MTLContext* mtlc;
} DLParams;
jint redrawCount;
jint avgDisplayLinkSamples;
CFTimeInterval lastRedrawTime;
CFTimeInterval lastDisplayLinkTime;
CFTimeInterval avgDisplayLinkTime;
CFTimeInterval lastStatTime;
} MTLDisplayLinkState;
@implementation MTLCommandBufferWrapper {
id<MTLCommandBuffer> _commandBuffer;
@@ -142,13 +170,7 @@ typedef struct {
@implementation MTLContext {
MTLCommandBufferWrapper * _commandBufferWrapper;
NSMutableSet* _layers;
int _displayLinkCount;
CFTimeInterval _lastDisplayLinkTime;
CFTimeInterval _avgDisplayLinkTime;
CFTimeInterval _lastRedrawTime;
CFTimeInterval _lastStatTime;
NSMutableSet* _layers;
MTLComposite * _composite;
MTLPaint * _paint;
@@ -157,7 +179,7 @@ typedef struct {
MTLClip * _clip;
NSObject* _bufImgOp; // TODO: pass as parameter of IsoBlit
EncoderManager * _encoderManager;
EncoderManager * _encoderManager;
MTLSamplerManager * _samplerManager;
MTLStencilManager * _stencilManager;
}
@@ -171,19 +193,107 @@ typedef struct {
extern void initSamplers(id<MTLDevice> device);
+ (void)mtlc_systemOrScreenWillSleep:(NSNotification*)notification {
if (TRACE_PWM_NOTIF) {
NSLog(@"MTLContext_systemOrScreenWillSleep[%@]", [notification name]);
}
if (isDisplaySyncEnabled()) {
[ThreadUtilities performOnMainThreadNowOrLater:NO // critical
block:^(){
for (MTLContext *mtlc in [MTLContext.contextStore allValues]) {
const NSArray<NSNumber*> *displayIDs = [mtlc getDisplayLinkDisplayIds]; // old ids
if (TRACE_PWM_NOTIF) {
NSLog(@"MTLContext_systemOrScreenWillSleep: ctx=%p (%d displayLinks)",
mtlc, (int) displayIDs.count);
}
for (NSNumber* displayIDVal in displayIDs) {
const jint displayID = [displayIDVal intValue];
const BOOL active = mtlc_IsDisplayReallyActive(displayID);
if (TRACE_PWM_NOTIF) {
NSLog(@"MTLContext_systemOrScreenWillSleep: displayId=%d active=%d", displayID, active);
}
if (TRACE_DISPLAY) {
[MTLContext dumpDisplayInfo:displayID];
}
if ((notification.name == NSWorkspaceWillSleepNotification)|| !active) {
[mtlc destroyDisplayLink:displayID];
}
}
}
}];
}
}
+ (void)mtlc_systemOrScreenDidWake:(NSNotification*)notification {
if (TRACE_PWM_NOTIF) {
NSLog(@"MTLContext_systemOrScreenDidWake[%@]", [notification name]);
}
if (isDisplaySyncEnabled()) {
[ThreadUtilities performOnMainThreadNowOrLater:NO // critical
block:^(){
for (MTLContext *mtlc in [MTLContext.contextStore allValues]) {
const NSArray<NSNumber*>* displayIDs = [mtlc getDisplayLinkDisplayIds]; // old ids
if (TRACE_PWM_NOTIF) {
NSLog(@"MTLContext_systemOrScreenDidWake: ctx=%p (%d displayLinks)",
mtlc, (int)displayIDs.count);
}
for (NSNumber* displayIDVal in displayIDs) {
const jint displayID = [displayIDVal intValue];
const BOOL active = mtlc_IsDisplayReallyActive(displayID);
if (TRACE_PWM_NOTIF) {
NSLog(@"MTLContext_systemOrScreenDidWake: displayId=%d active=%d", displayID, active);
}
if (TRACE_DISPLAY) {
[MTLContext dumpDisplayInfo:displayID];
}
if (active) {
// (if needed will start a new display link thread):
[mtlc createDisplayLinkIfAbsent:displayID];
}
}
}
}];
}
}
+ (void)registerForSystemAndScreenNotifications {
static BOOL notificationRegistered = false;
if (!notificationRegistered) {
notificationRegistered = true;
NSNotificationCenter *ctr = [[NSWorkspace sharedWorkspace] notificationCenter];
Class clz = [MTLContext class];
[ctr addObserver:clz selector:@selector(mtlc_systemOrScreenWillSleep:) name:NSWorkspaceWillSleepNotification object:nil];
[ctr addObserver:clz selector:@selector(mtlc_systemOrScreenDidWake:) name:NSWorkspaceDidWakeNotification object:nil];
// NSWorkspaceScreensDidWakeNotification is first sent:
[ctr addObserver:clz selector:@selector(mtlc_systemOrScreenWillSleep:) name:NSWorkspaceScreensDidSleepNotification object:nil];
[ctr addObserver:clz selector:@selector(mtlc_systemOrScreenDidWake:) name:NSWorkspaceScreensDidWakeNotification object:nil];
}
}
+ (NSMutableDictionary*) contextStore {
static NSMutableDictionary<NSNumber*, MTLContext*> *_contextStore;
static NSMutableDictionary<id<NSCopying>, MTLContext*> *_contextStore;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_contextStore = [[NSMutableDictionary alloc] init];
});
[MTLContext registerForSystemAndScreenNotifications];
});
return _contextStore;
}
+ (MTLContext*) createContextWithDeviceIfAbsent:(jint)displayID shadersLib:(NSString*)mtlShadersLib {
// Initialization code here.
// note: the device reference is NS_RETURNS_RETAINED, should be released by the caller:
bool shouldReleaseDevice = true;
id<MTLDevice> device = CGDirectDisplayCopyCurrentMetalDevice(displayID);
if (device == nil) {
J2dRlsTraceLn1(J2D_TRACE_ERROR, "MTLContext_createContextWithDeviceIfAbsent(): Cannot create device from "
@@ -200,61 +310,73 @@ extern void initSamplers(id<MTLDevice> device);
}
}
id<NSCopying> devID = nil;
id<NSCopying> deviceID = nil;
if (@available(macOS 10.13, *)) {
devID = @(device.registryID);
deviceID = @(device.registryID);
} else {
devID = device.name;
deviceID = device.name;
}
MTLContext* mtlc = MTLContext.contextStore[devID];
MTLContext* mtlc = MTLContext.contextStore[deviceID];
if (mtlc == nil) {
mtlc = [[MTLContext alloc] initWithDevice:device display:displayID shadersLib:mtlShadersLib];
mtlc = [[MTLContext alloc] initWithDevice:device shadersLib:mtlShadersLib];
if (mtlc != nil) {
MTLContext.contextStore[devID] = mtlc;
shouldReleaseDevice = false;
// transfer ownership (objc ref):
MTLContext.contextStore[deviceID] = mtlc;
[mtlc release];
J2dRlsTraceLn4(J2D_TRACE_INFO,
"MTLContext_createContextWithDeviceIfAbsent: new context(%p) for display=%d device=\"%s\" "
"retainCount=%d", mtlc, displayID, [mtlc.device.name UTF8String], mtlc.retainCount)
"retainCount=%d", mtlc, displayID, [mtlc.device.name UTF8String],
mtlc.retainCount);
}
} else {
if (![mtlc.shadersLib isEqualToString:mtlShadersLib]) {
J2dRlsTraceLn3(J2D_TRACE_ERROR,
"MTLContext_createContextWithDeviceIfAbsent: cannot reuse context(%p) for display=%d "
"device=\"%s\", shaders lib has been changed", mtlc, displayID, [mtlc.device.name UTF8String])
[device release];
return nil;
}
[mtlc retain];
J2dRlsTraceLn4(J2D_TRACE_INFO,
"MTLContext_createContextWithDeviceIfAbsent: reuse context(%p) for display=%d device=\"%s\" "
"retainCount=%d", mtlc, displayID, [mtlc.device.name UTF8String], mtlc.retainCount)
"retainCount=%d", mtlc, displayID, [mtlc.device.name UTF8String],
mtlc.retainCount);
}
if (shouldReleaseDevice) {
[device release];
}
// (will start a new display link thread if needed):
[mtlc createDisplayLinkIfAbsent:displayID];
return mtlc;
}
+ (void) releaseContext:(MTLContext*) mtlc {
id<NSCopying> devID = nil;
id<NSCopying> deviceID = nil;
if (@available(macOS 10.13, *)) {
devID = @(mtlc.device.registryID);
deviceID = @(mtlc.device.registryID);
} else {
devID = mtlc.device.name;
deviceID = mtlc.device.name;
}
MTLContext* ctx = MTLContext.contextStore[devID];
MTLContext* ctx = MTLContext.contextStore[deviceID];
if (mtlc == ctx) {
if (mtlc.retainCount > 1) {
[mtlc release];
J2dRlsTraceLn2(J2D_TRACE_INFO, "MTLContext_releaseContext: release context(%p) retainCount=%d", mtlc, mtlc.retainCount);
} else {
[MTLContext.contextStore removeObjectForKey:devID];
// explicit halt redraw to shutdown CVDisplayLink threads before dealloc():
[mtlc haltRedraw];
// remove ownership (objc ref):
[MTLContext.contextStore removeObjectForKey:deviceID];
J2dRlsTraceLn1(J2D_TRACE_INFO, "MTLContext_releaseContext: dealloc context(%p)", mtlc);
}
} else {
J2dRlsTraceLn2(J2D_TRACE_ERROR, "MTLContext_releaseContext: cannot release context(%p) != context store(%p)",
mtlc, ctx);
}
}
- (id)initWithDevice:(id<MTLDevice>)mtlDevice display:(jint) displayID shadersLib:(NSString*)mtlShadersLib {
- (id)initWithDevice:(id<MTLDevice>)mtlDevice shadersLib:(NSString*)mtlShadersLib {
self = [super init];
if (self) {
device = mtlDevice;
@@ -288,14 +410,13 @@ extern void initSamplers(id<MTLDevice> device);
blitCommandQueue = [device newCommandQueue];
_tempTransform = [[MTLTransform alloc] init];
_displayLinkCount = 0;
_lastDisplayLinkTime = 0;
_avgDisplayLinkTime = 0;
_lastRedrawTime = 0.0;
_lastStatTime = 0.0;
if (isDisplaySyncEnabled()) {
_displayLinks = [[NSMutableDictionary alloc] init];
_displayLinkStates = [[NSMutableDictionary alloc] init];
_layers = [[NSMutableSet alloc] init];
} else {
_displayLinkStates = nil;
_layers = nil;
}
_glyphCacheLCD = [[MTLGlyphCache alloc] initWithContext:self];
_glyphCacheAA = [[MTLGlyphCache alloc] initWithContext:self];
@@ -397,67 +518,140 @@ extern void initSamplers(id<MTLDevice> device);
}
}
- (NSArray<NSNumber*>*)getDisplayLinkDisplayIds {
return [_displayLinkStates allKeys];
}
- (void)createDisplayLinkIfAbsent: (jint)displayID {
if (isDisplaySyncEnabled() && _displayLinks[@(displayID)] == nil) {
if (isDisplaySyncEnabled()) {
MTLDisplayLinkState *dlState = [self getDisplayLinkState:displayID];
if ((dlState != nil) && (dlState->displayLink != nil)) {
return;
}
if (TRACE_DISPLAY) {
[MTLContext dumpDisplayInfo:displayID];
}
CVDisplayLinkRef _displayLink;
if (TRACE_CVLINK) {
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_createDisplayLinkIfAbsent: "
"ctx=%p displayID=%d", self, displayID);
}
CHECK_CVLINK("CreateWithCGDisplay", nil,
CHECK_CVLINK("CreateWithCGDisplay", nil, &_displayLink,
CVDisplayLinkCreateWithCGDisplay(displayID, &_displayLink));
if (_displayLink == nil) {
J2dRlsTraceLn(J2D_TRACE_ERROR,
"MTLContext_createDisplayLinkIfAbsent: Failed to initialize CVDisplayLink.");
} else {
DLParams* dlParams = malloc(sizeof (DLParams ));
dlParams->displayID = displayID;
dlParams->displayLink = _displayLink;
dlParams->mtlc = self;
_displayLinks[@(displayID)] = [NSValue valueWithPointer:dlParams];
CHECK_CVLINK("SetOutputCallback", nil,
J2dRlsTraceLn3(J2D_TRACE_INFO, "MTLContext_destroyDisplayLinkMTLContext_createDisplayLinkIfAbsent["
"ctx=%p displayID=%d] displayLink=%p",
self, displayID, _displayLink);
bool isNewDisplayLink = false;
if (dlState == nil) {
dlState = malloc(sizeof(MTLDisplayLinkState));
isNewDisplayLink = true;
}
// update:
dlState->displayID = displayID;
dlState->displayLink = _displayLink;
dlState->mtlc = self;
dlState->redrawCount = 0;
dlState->avgDisplayLinkSamples = 0;
dlState->lastRedrawTime = 0.0;
dlState->lastDisplayLinkTime = 0.0;
dlState->avgDisplayLinkTime = 0.0;
dlState->lastStatTime = 0.0;
if (isNewDisplayLink) {
// publish fully initialized object:
_displayLinkStates[@(displayID)] = [NSValue valueWithPointer:dlState];
}
CHECK_CVLINK("SetOutputCallback", nil, &_displayLink,
CVDisplayLinkSetOutputCallback(_displayLink, &mtlDisplayLinkCallback,
(__bridge DLParams*) dlParams));
(__bridge MTLDisplayLinkState*) dlState));
}
}
}
- (void)handleDisplayLink: (BOOL)enabled display:(jint) display source:(const char*)src {
if (_displayLinks == nil) {
if (TRACE_CVLINK) {
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_handleDisplayLink[%s]: "
"ctx=%p - displayLinks = nil", src, self);
- (NSValue*)getDisplayLinkState: (jint)displayID {
if (_displayLinkStates == nil) {
if (TRACE_CVLINK_WARN) {
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_getDisplayLinkState[ctx=%p displayID=%d]: "
"displayLinkStates is nil!", self, displayID);
}
} else {
NSValue* dlParamsVal = _displayLinks[@(display)];
if (dlParamsVal == nil) {
J2dRlsTraceLn3(J2D_TRACE_ERROR, "MTLContext_handleDisplayLink[%s]: "
"ctx=%p, no display link for %d ", src, self, display);
return nil;
}
NSValue* dlStateVal = _displayLinkStates[@(displayID)];
if (dlStateVal == nil) {
if (TRACE_CVLINK_WARN) {
J2dRlsTraceLn2(J2D_TRACE_ERROR, "MTLContext_getDisplayLinkState[ctx=%p displayID=%d]: "
"dlState is nil!", self, displayID);
}
return nil;
}
return [dlStateVal pointerValue];
}
- (void)destroyDisplayLink: (jint)displayID {
if (isDisplaySyncEnabled()) {
MTLDisplayLinkState *dlState = [self getDisplayLinkState:displayID];
if (dlState == nil) {
return;
}
DLParams *dlParams = [dlParamsVal pointerValue];
CVDisplayLinkRef _displayLink = dlParams->displayLink;
if (enabled) {
if (!CVDisplayLinkIsRunning(_displayLink)) {
CHECK_CVLINK("Start", src, CVDisplayLinkStart(_displayLink));
if (TRACE_CVLINK) {
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_CVDisplayLinkStart[%s]: "
"ctx=%p", src, self);
}
CVDisplayLinkRef _displayLink = dlState->displayLink;
if (_displayLink == nil) {
return;
}
if (TRACE_CVLINK) {
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_destroyDisplayLink: "
"ctx=%p, displayID=%d", self, displayID);
}
if (CVDisplayLinkIsRunning(_displayLink)) {
CHECK_CVLINK("Stop", "destroyDisplayLink", &_displayLink,
CVDisplayLinkStop(_displayLink));
}
J2dRlsTraceLn3(J2D_TRACE_INFO, "MTLContext_destroyDisplayLink["
"ctx=%p displayID=%d] displayLink=%p",
self, displayID, _displayLink);
// Release display link thread:
CVDisplayLinkRelease(_displayLink);
dlState->displayLink = nil;
}
}
- (void)handleDisplayLink: (BOOL)enabled displayID:(jint)displayID source:(const char*)src {
MTLDisplayLinkState *dlState = [self getDisplayLinkState:displayID];
if (dlState == nil) {
return;
}
CVDisplayLinkRef _displayLink = dlState->displayLink;
if (_displayLink == nil) {
if (TRACE_CVLINK) {
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, "MTLContext_handleDisplayLink[%s]: "
"displayLink is nil (disabled).", src);
}
return;
}
if (enabled) {
if (!CVDisplayLinkIsRunning(_displayLink)) {
CHECK_CVLINK("Start", src, &_displayLink,
CVDisplayLinkStart(_displayLink));
if (TRACE_CVLINK) {
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_CVDisplayLinkStart[%s]: "
"ctx=%p", src, self);
}
} else {
if (CVDisplayLinkIsRunning(_displayLink)) {
CHECK_CVLINK("Stop", src, CVDisplayLinkStop(_displayLink));
if (TRACE_CVLINK) {
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_CVDisplayLinkStop[%s]: "
"ctx=%p", src, self);
}
}
} else {
if (CVDisplayLinkIsRunning(_displayLink)) {
CHECK_CVLINK("Stop", src, &_displayLink,
CVDisplayLinkStop(_displayLink));
if (TRACE_CVLINK) {
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_CVDisplayLinkStop[%s]: "
"ctx=%p", src, self);
}
}
}
@@ -466,8 +660,10 @@ extern void initSamplers(id<MTLDevice> device);
- (void)dealloc {
J2dTraceLn(J2D_TRACE_INFO, "MTLContext.dealloc");
if (_displayLinks != nil) {
if (_displayLinkStates != nil) {
[self haltRedraw];
[_displayLinkStates release];
_displayLinkStates = nil;
}
[shadersLib release];
@@ -538,7 +734,7 @@ extern void initSamplers(id<MTLDevice> device);
- (MTLCommandBufferWrapper *) getCommandBufferWrapper {
if (_commandBufferWrapper == nil) {
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLContext : commandBuffer is NULL");
J2dTraceLn(J2D_TRACE_VERBOSE, "MTLContext : commandBuffer is nil!");
// NOTE: Command queues are thread-safe and allow multiple outstanding command buffers to be encoded simultaneously.
_commandBufferWrapper = [[MTLCommandBufferWrapper alloc] initWithCommandBuffer:[self.commandQueue commandBuffer]];// released in [layer blitTexture]
}
@@ -814,7 +1010,7 @@ extern void initSamplers(id<MTLDevice> device);
MTLCommandBufferWrapper * cbwrapper = [self pullCommandBufferWrapper];
if (cbwrapper != nil) {
id <MTLCommandBuffer> commandbuf =[cbwrapper getCommandBuffer];
[commandbuf addCompletedHandler:^(id <MTLCommandBuffer> commandbuf) {
[commandbuf addCompletedHandler:^(id <MTLCommandBuffer> cb) {
[cbwrapper release];
}];
[commandbuf commit];
@@ -825,94 +1021,169 @@ extern void initSamplers(id<MTLDevice> device);
}
}
- (void) redraw:(NSNumber*)displayIDNum {
- (void) redraw:(NSNumber*)displayIDNumber {
AWT_ASSERT_APPKIT_THREAD;
const CFTimeInterval now = CACurrentMediaTime();
const jint displayID = [displayIDNumber intValue];
MTLDisplayLinkState *dlState = [self getDisplayLinkState:displayID];
if (dlState == nil) {
return;
}
/*
* Avoid repeated invocations by UIKit Main Thread
* if blocked while many mtlDisplayLinkCallback() are dispatched
*/
const CFTimeInterval now = CACurrentMediaTime();
const CFTimeInterval elapsed = (_lastRedrawTime != 0.0) ? (now - _lastRedrawTime) : -1.0;
const CFTimeInterval elapsed = (dlState->lastRedrawTime != 0.0) ? (now - dlState->lastRedrawTime) : -1.0;
if ((elapsed >= 0.0) && (elapsed <= KEEP_ALIVE_MIN_INTERVAL)) {
CFTimeInterval threshold = (dlState->avgDisplayLinkSamples >= 10) ?
(dlState->avgDisplayLinkTime / 20.0) : KEEP_ALIVE_MIN_INTERVAL;
if (threshold < KEEP_ALIVE_MIN_INTERVAL) {
threshold = KEEP_ALIVE_MIN_INTERVAL;
}
if ((elapsed >= 0.0) && (elapsed <= threshold)) {
if (TRACE_CVLINK) {
NSLog(@"MTLContext_redraw[displayID: %d]: %.3f < %.3f ms, skip redraw.",
displayID, TO_MS(elapsed), TO_MS(threshold));
}
return;
}
_lastRedrawTime = now;
if (TRACE_CVLINK_DEBUG) {
NSLog(@"MTLContext_redraw[displayID: %d]: elapsed: %.3f ms (> %.3f)",
displayID, TO_MS(elapsed), TO_MS(threshold));
}
dlState->lastRedrawTime = now;
// Process layers:
for (MTLLayer *layer in _layers) {
[layer setNeedsDisplay];
}
if (_displayLinkCount > 0) {
_displayLinkCount--;
} else {
if (_layers.count > 0) {
[_layers removeAllObjects];
if (layer.displayID == displayID) {
[layer setNeedsDisplay];
}
[self handleDisplayLink:NO display:[displayIDNum integerValue] source:"redraw"];
}
if (dlState->redrawCount > 0) {
dlState->redrawCount--;
} else {
// dlState->redrawCount == 0:
if (_layers.count > 0) {
for (MTLLayer *layer in _layers.allObjects) {
if (layer.displayID == displayID) {
[_layers removeObject:layer];
}
}
}
[self handleDisplayLink:NO displayID:displayID source:"redraw"];
}
}
CVReturn mtlDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* nowTime, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
J2dTraceLn1(J2D_TRACE_VERBOSE, "MTLContext_mtlDisplayLinkCallback: ctx=%p", displayLinkContext);
@autoreleasepool {
const DLParams* dlParams = (__bridge DLParams* *)displayLinkContext;
const MTLContext* mtlc = dlParams->mtlc;
const jint displayID = dlParams->displayID;
CVReturn mtlDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* nowTime, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) {
JNI_COCOA_ENTER(env);
J2dTraceLn1(J2D_TRACE_VERBOSE, "MTLContext_mtlDisplayLinkCallback: ctx=%p", displayLinkContext);
MTLDisplayLinkState *dlState = (__bridge MTLDisplayLinkState*) displayLinkContext;
if (dlState == nil) {
if (TRACE_CVLINK_WARN) {
NSLog(@"MTLContext_mtlDisplayLinkCallback: dlState is nil!");
}
return kCVReturnError;
}
const MTLContext *mtlc = dlState->mtlc;
const jint displayID = dlState->displayID;
if (STATS_CVLINK) {
const CFTimeInterval now = outputTime->videoTime / (double)outputTime->videoTimeScale; // seconds
const CFTimeInterval delta = (mtlc->_lastDisplayLinkTime != 0.0) ? (now - mtlc->_lastDisplayLinkTime) : -1.0;
mtlc->_lastDisplayLinkTime = now;
const CFTimeInterval now = outputTime->videoTime / (double) outputTime->videoTimeScale; // seconds
const CFTimeInterval delta = (dlState->lastDisplayLinkTime != 0.0) ? (now - dlState->lastDisplayLinkTime)
: -1.0;
dlState->lastDisplayLinkTime = now;
const NSTimeInterval a = 1.0 / 30.0; // 60 fps typically => exponential smoothing on 0.5s:
mtlc->_avgDisplayLinkTime = delta * a + mtlc->_avgDisplayLinkTime * (1.0 - a);
dlState->avgDisplayLinkSamples++;
dlState->avgDisplayLinkTime = EXP_AVG_WEIGHT * delta + EXP_INV_WEIGHT * dlState->avgDisplayLinkTime;
if (mtlc->_lastStatTime == 0.0) {
mtlc->_lastStatTime = now;
} else if ((now - mtlc->_lastStatTime) > 1.0) {
mtlc->_lastStatTime = now;
if (dlState->lastStatTime == 0.0) {
dlState->lastStatTime = now;
} else if ((now - dlState->lastStatTime) > 1.0) {
dlState->lastStatTime = now;
// dump stats:
NSLog(@"mtlDisplayLinkCallback[%d]: avgDisplayLinkTime = %.3lf ms", displayID,
1000.0 * mtlc->_avgDisplayLinkTime);
NSLog(@"mtlDisplayLinkCallback[displayID: %d]: avg interval = %.3lf ms (%.1lf fps) on %d samples", displayID,
TO_MS(dlState->avgDisplayLinkTime), TO_FPS(dlState->avgDisplayLinkTime), dlState->avgDisplayLinkSamples);
}
}
[ThreadUtilities performOnMainThread:@selector(redraw:) on:mtlc withObject:@(displayID)
waitUntilDone:NO useJavaModes:NO]; // critical
}
const BOOL active = mtlc_IsDisplayReallyActive(displayID);
if (TRACE_CVLINK_DEBUG) {
NSLog(@"MTLContext_mtlDisplayLinkCallback: ctx=%p displayID=%d active=%d (display link = %p)",
mtlc, displayID, active, dlState->displayLink);
}
if (!active) {
if (TRACE_CVLINK) {
NSLog(@"MTLContext_mtlDisplayLinkCallback: displayId=%d active=%d "
"=> destroyDisplayLink", displayID, active);
}
if (TRACE_DISPLAY) {
[MTLContext dumpDisplayInfo:displayID];
}
[mtlc destroyDisplayLink:displayID];
} else {
[ThreadUtilities performOnMainThread:@selector(redraw:) on:mtlc withObject:@(displayID)
waitUntilDone:NO useJavaModes:NO]; // critical
}
JNI_COCOA_EXIT(env);
return kCVReturnSuccess;
}
- (void)startRedraw:(MTLLayer*)layer {
AWT_ASSERT_APPKIT_THREAD;
layer.redrawCount = REDRAW_COUNT;
J2dTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_startRedraw: ctx=%p layer=%p", self, layer);
_displayLinkCount = KEEP_ALIVE_COUNT;
const jint displayID = layer.displayID;
MTLDisplayLinkState *dlState = [self getDisplayLinkState:displayID];
if (dlState == nil) {
return;
}
dlState->redrawCount = KEEP_ALIVE_COUNT;
layer.redrawCount = REDRAW_COUNT;
[_layers addObject:layer];
if (MTLLayer_isExtraRedrawEnabled()) {
// Request for redraw before starting display link to avoid rendering problem on M2 processor
[layer setNeedsDisplay];
}
[self handleDisplayLink:YES display:layer.displayID source:"startRedraw"];
[self handleDisplayLink:YES displayID:displayID source:"startRedraw"];
}
- (void)stopRedraw:(MTLLayer*) layer {
[self stopRedraw:layer.displayID layer:layer];
}
- (void)stopRedraw:(jint)displayID layer:(MTLLayer*)layer {
AWT_ASSERT_APPKIT_THREAD;
J2dTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_stopRedraw: ctx=%p layer=%p", self, layer);
if (_displayLinks != nil) {
if (--layer.redrawCount <= 0) {
[_layers removeObject:layer];
layer.redrawCount = 0;
}
if ((_layers.count == 0) && (_displayLinkCount == 0)) {
[self handleDisplayLink:NO display:layer.displayID source:"stopRedraw"];
J2dTraceLn3(J2D_TRACE_VERBOSE, "MTLContext_stopRedraw: ctx=%p displayID=%d layer=%p",
self, displayID, layer);
MTLDisplayLinkState *dlState = [self getDisplayLinkState:displayID];
if (dlState == nil) {
return;
}
if (--layer.redrawCount <= 0) {
[_layers removeObject:layer];
layer.redrawCount = 0;
}
bool hasLayers = false;
if (_layers.count > 0) {
for (MTLLayer *l in _layers) {
if (l.displayID == displayID) {
hasLayers = true;
break;
}
}
}
if (!hasLayers && (dlState->redrawCount == 0)) {
[self handleDisplayLink:NO displayID:displayID source:"stopRedraw"];
}
}
- (void)haltRedraw {
if (_displayLinks != nil) {
if (_displayLinkStates != nil) {
if (TRACE_CVLINK) {
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, "MTLContext_haltRedraw: ctx=%p", self);
}
@@ -922,17 +1193,19 @@ CVReturn mtlDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp*
}
[_layers removeAllObjects];
}
_displayLinkCount = 0;
NSEnumerator<NSNumber*>* keyEnum = _displayLinks.keyEnumerator;
NSNumber* displayIDVal;
while ((displayIDVal = [keyEnum nextObject])) {
[self handleDisplayLink:NO display:[displayIDVal integerValue] source:"haltRedraw"];
DLParams *dlParams = [(NSValue*)_displayLinks[displayIDVal] pointerValue];
CVDisplayLinkRelease(dlParams->displayLink);
free(dlParams);
if (_displayLinkStates.count > 0) {
for (NSNumber* displayIDVal in [self getDisplayLinkDisplayIds]) {
const jint displayID = [displayIDVal intValue];
[self destroyDisplayLink:displayID];
MTLDisplayLinkState *dlState = [self getDisplayLinkState:displayID];
if (dlState != nil) {
// Remove reference:
[_displayLinkStates removeObjectForKey:@(displayID)];
free(dlState);
}
}
}
[_displayLinks release];
_displayLinks = NULL;
}
}

View File

@@ -59,6 +59,7 @@
- (void) startRedraw;
- (void) startRedrawIfNeeded;
- (void) stopRedraw:(BOOL)force;
- (void) stopRedraw:(MTLContext*)mtlc displayID:(jint)displayID force:(BOOL)force;
- (void) flushBuffer;
- (void) commitCommandBuffer:(MTLContext*)mtlc wait:(BOOL)waitUntilCompleted display:(BOOL)updateDisplay;
- (void) countFramePresentedCallback;

View File

@@ -39,7 +39,8 @@ static jclass jc_JavaLayer = NULL;
#define GET_MTL_LAYER_CLASS() \
GET_CLASS(jc_JavaLayer, "sun/java2d/metal/MTLLayer");
#define TRACE_DISPLAY 0
#define TRACE_DISPLAY 0
#define TRACE_DISPLAY_CHANGED 0
const NSTimeInterval DF_BLIT_FRAME_TIME=1.0/120.0;
@@ -120,7 +121,8 @@ BOOL MTLLayer_isExtraRedrawEnabled() {
if (self == nil) return self;
self.javaLayer = layer;
self.ctx = nil;
self.displayID = -1;
self.contentsGravity = kCAGravityTopLeft;
//Disable CALayer's default animation
@@ -417,14 +419,20 @@ BOOL MTLLayer_isExtraRedrawEnabled() {
}
- (void)stopRedraw:(BOOL)force {
if (isDisplaySyncEnabled()) {
[self stopRedraw:self.ctx displayID:self.displayID force:force];
}
}
- (void) stopRedraw:(MTLContext*)mtlc displayID:(jint)displayID force:(BOOL)force {
if (isDisplaySyncEnabled()) {
if (force) {
self.redrawCount = 0;
}
if (self.ctx != nil) {
if (mtlc != nil) {
[ThreadUtilities performOnMainThreadNowOrLater:NO // critical
block:^(){
[self.ctx stopRedraw:self];
[mtlc stopRedraw:displayID layer:self];
}];
}
}
@@ -557,9 +565,31 @@ Java_sun_java2d_metal_MTLLayer_validate
BMTLSDOps *bmtlsdo = (BMTLSDOps*) SurfaceData_GetOps(env, surfaceData);
layer.buffer = &bmtlsdo->pTexture;
layer.outBuffer = &bmtlsdo->pOutTexture;
layer.ctx = ((MTLSDOps *)bmtlsdo->privOps)->configInfo->context;
layer.displayID = ((MTLSDOps *)bmtlsdo->privOps)->configInfo->displayID;
layer.device = layer.ctx.device;
// Backup layer's context (device) and displayId to unregister if needed:
MTLContext* oldMtlc = layer.ctx;
NSInteger oldDisplayID = layer.displayID;
MTLContext* newMtlc = ((MTLSDOps *)bmtlsdo->privOps)->configInfo->context;
NSInteger newDisplayID = ((MTLSDOps *)bmtlsdo->privOps)->configInfo->displayID;
if (isDisplaySyncEnabled()) {
if (oldDisplayID != -1) {
if ((oldMtlc != newMtlc) || (oldDisplayID != newDisplayID)) {
if (TRACE_DISPLAY_CHANGED) {
J2dRlsTraceLn5(J2D_TRACE_INFO, "MTLLayer_validate: layer[%p] mtlc/displayID changed: "
"[%p - %d] => [%p - %d]",
layer, oldMtlc, oldDisplayID, newMtlc, newDisplayID);
}
// unregister with display link on old mtlc/display before updating layer's state:
[layer stopRedraw:oldMtlc displayID:oldDisplayID force:YES];
}
}
}
// Update layer's context (device) and displayId:
layer.ctx = newMtlc;
layer.device = layer.ctx.device;
layer.displayID = newDisplayID;
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
if (!isColorMatchingEnabled() && (layer.colorspace != nil)) {
@@ -570,6 +600,7 @@ Java_sun_java2d_metal_MTLLayer_validate
layer.drawableSize =
CGSizeMake((*layer.buffer).width,
(*layer.buffer).height);
if (isDisplaySyncEnabled()) {
[layer startRedraw];
} else {

View File

@@ -27,6 +27,7 @@
#define __THREADUTILITIES_H
#import <Foundation/Foundation.h>
#import <stdatomic.h>
#include "jni.h"
@@ -174,14 +175,21 @@ __attribute__((visibility("default")))
+ (NSString*)criticalRunLoopMode;
+ (NSString*)javaRunLoopMode;
+ (ThreadTraceContext*) getTraceContext;
+ (void) removeTraceContext;
+ (void) resetTraceContext;
+ (ThreadTraceContext*)getTraceContext;
+ (void)removeTraceContext;
+ (void)resetTraceContext;
+ (ThreadTraceContext*)recordTraceContext;
+ (ThreadTraceContext*)recordTraceContext:(NSString*) prefix;
+ (ThreadTraceContext*)recordTraceContext:(NSString*)prefix;
+ (ThreadTraceContext*)recordTraceContext:(NSString*)prefix actionId:(long)actionId useJavaModes:(BOOL)useJavaModes operation:(char*) operation;
+ (NSString*)getThreadTraceContexts;
+ (void)registerForSystemAndScreenNotifications;
+ (BOOL)isWithinPowerTransition;
+ (BOOL)nanoUpTime:(atomic_uint_least64_t*)nanotime;
+ (BOOL)nowNearTime:(NSString*)src refTime:(atomic_uint_least64_t*)refTime;
@end
JNIEXPORT void OSXAPP_SetJavaVM(JavaVM *vm);

View File

@@ -25,7 +25,6 @@
#import <AppKit/AppKit.h>
#import <objc/message.h>
#import <stdatomic.h>
#import "JNIUtilities.h"
#import "PropertiesUtilities.h"
@@ -61,6 +60,7 @@ static const char* toCString(id obj) {
JavaVM *jvm = NULL;
static JNIEnv *appKitEnv = NULL;
static jobject appkitThreadGroup = NULL;
static NSString* CriticalRunLoopMode = @"AWTCriticalRunLoopMode";
static NSString* JavaRunLoopMode = @"AWTRunLoopMode";
static NSArray<NSString*> *javaModes = nil;
@@ -68,13 +68,28 @@ static NSArray<NSString*> *allModesExceptJava = nil;
/* Traceability data */
static const BOOL enableTracing = NO;
static const BOOL enableTracingLog = NO;
static const BOOL enableCallStacks = NO;
static const BOOL enableRunLoopObserver = NO;
/* Traceability data */
static const BOOL TRACE_PWM = NO;
static const BOOL TRACE_PWM_EVENTS = NO;
static const BOOL TRACE_CLOCKS = NO;
/* 10s period arround reference times (sleep/wake-up...)
* to ensure all displays are awaken properly */
static const uint64_t NANOS_PER_SEC = 1000000000ULL;
static const uint64_t RDV_PERIOD = 10ULL * NANOS_PER_SEC;
/* RunLoop traceability identifier generators */
static atomic_long runLoopId = 0L;
static atomic_long mainThreadActionId = 0L;
static atomic_uint_least64_t sleepTime = 0LL;
static atomic_uint_least64_t wakeUpTime = 0LL;
static inline void attachCurrentThread(void** env) {
if ([NSThread isMainThread]) {
JavaVMAttachArgs args;
@@ -148,66 +163,71 @@ AWT_ASSERT_APPKIT_THREAD;
if (enableTracing) {
// Record thread stack now and return another copy (auto-released):
[ThreadUtilities recordTraceContext];
if (enableRunLoopObserver) {
CFRunLoopObserverRef logObserver = CFRunLoopObserverCreateWithHandler(
NULL, // CFAllocator
kCFRunLoopAllActivities, // CFOptionFlags
true, // repeats
NSIntegerMin, // order = max priority
^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
if ([[NSThread currentThread] isMainThread]) {
char* activityName = NULL;
switch (activity) {
default:
break;
case kCFRunLoopEntry:
activityName = "RunLoopEntry";
/* Increment global main RunLoop id */
runLoopId++;
break;
case kCFRunLoopBeforeTimers:
activityName = "RunLoopBeforeTimers";
break;
case kCFRunLoopBeforeSources :
activityName = "RunLoopBeforeSources";
break;
case kCFRunLoopBeforeWaiting:
activityName = "RunLoopBeforeWaiting";
break;
case kCFRunLoopAfterWaiting:
activityName = "RunLoopAfterWaiting";
break;
case kCFRunLoopExit:
activityName = "RunLoopExit";
break;
case kCFRunLoopAllActivities:
activityName = "RunLoopAllActivities";
break;
@try {
if (enableRunLoopObserver) {
CFRunLoopObserverRef logObserver = CFRunLoopObserverCreateWithHandler(
NULL, // CFAllocator
kCFRunLoopAllActivities, // CFOptionFlags
true, // repeats
NSIntegerMin, // order = max priority
^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
if ([[NSThread currentThread] isMainThread]) {
char *activityName = NULL;
switch (activity) {
default:
break;
case kCFRunLoopEntry:
activityName = "RunLoopEntry";
/* Increment global main RunLoop id */
runLoopId++;
break;
case kCFRunLoopBeforeTimers:
activityName = "RunLoopBeforeTimers";
break;
case kCFRunLoopBeforeSources :
activityName = "RunLoopBeforeSources";
break;
case kCFRunLoopBeforeWaiting:
activityName = "RunLoopBeforeWaiting";
break;
case kCFRunLoopAfterWaiting:
activityName = "RunLoopAfterWaiting";
break;
case kCFRunLoopExit:
activityName = "RunLoopExit";
break;
case kCFRunLoopAllActivities:
activityName = "RunLoopAllActivities";
break;
}
if (activityName != NULL) {
NSLog(@"RunLoop[on %s][%lu]: processing %s on mode = '%@'",
NSThread.currentThread.name.UTF8String, runLoopId, activityName,
NSRunLoop.currentRunLoop.currentMode);
}
}
}
if (activityName != NULL) {
NSLog(@"RunLoop[on %s][%lu]: processing %s on mode = '%@'",
NSThread.currentThread.name.UTF8String, runLoopId, activityName,
NSRunLoop.currentRunLoop.currentMode);
}
}
}
);
);
CFRunLoopRef runLoop = [[NSRunLoop mainRunLoop] getCFRunLoop];
CFRunLoopAddObserver(runLoop, logObserver, kCFRunLoopDefaultMode);
CFRunLoopRef runLoop = [[NSRunLoop mainRunLoop] getCFRunLoop];
CFRunLoopAddObserver(runLoop, logObserver, kCFRunLoopDefaultMode);
CFStringRef criticalModeRef = (__bridge CFStringRef)CriticalRunLoopMode;
CFRunLoopAddObserver(runLoop, logObserver, criticalModeRef);
CFStringRef criticalModeRef = (__bridge CFStringRef) CriticalRunLoopMode;
CFRunLoopAddObserver(runLoop, logObserver, criticalModeRef);
CFStringRef javaModeRef = (__bridge CFStringRef)JavaRunLoopMode;
CFRunLoopAddObserver(runLoop, logObserver, javaModeRef);
CFStringRef javaModeRef = (__bridge CFStringRef) JavaRunLoopMode;
CFRunLoopAddObserver(runLoop, logObserver, javaModeRef);
CFRelease(javaModeRef);
CFRelease(criticalModeRef);
CFRelease(logObserver);
CFRelease(javaModeRef);
CFRelease(criticalModeRef);
CFRelease(logObserver);
}
} @finally {
// Finally reset Main thread context in context store:
[ThreadUtilities resetTraceContext];
}
}
[ThreadUtilities registerForSystemAndScreenNotifications];
}
/*
@@ -217,8 +237,8 @@ AWT_ASSERT_APPKIT_THREAD;
* Note : if waiting cross-thread, possibly the stack allocated copy is accessible ?
*/
+ (void)invokeBlockCopy:(void (^)(void))blockCopy {
blockCopy();
Block_release(blockCopy);
blockCopy();
Block_release(blockCopy);
}
+ (NSString*)getCaller:(NSString*)prefixSymbol {
@@ -394,11 +414,12 @@ AWT_ASSERT_APPKIT_THREAD;
callerCtx = [ThreadUtilities recordTraceContext:nil actionId:actionId useJavaModes:useJavaModes operation:operation];
[callerCtx retain];
lwc_plog(env, "%s performOnMainThread[caller]", toCString([callerCtx description]));
if ([callerCtx callStack] != nil) {
lwc_plog(env, "%s performOnMainThread[caller]: call stack:\n%s",
[callerCtx identifier], toCString([callerCtx callStack]));
if (enableTracingLog) {
lwc_plog(env, "%s performOnMainThread[caller]", toCString([callerCtx description]));
if ([callerCtx callStack] != nil) {
lwc_plog(env, "%s performOnMainThread[caller]: call stack:\n%s",
[callerCtx identifier], toCString([callerCtx callStack]));
}
}
}
@@ -418,14 +439,16 @@ AWT_ASSERT_APPKIT_THREAD;
// Record thread stack now and return another copy (auto-released):
runCtx = [ThreadUtilities recordTraceContext];
const double latencyMs = ([runCtx timestamp] - [callerCtx timestamp]) * 1000.0;
if (enableTracingLog) {
const double latencyMs = ([runCtx timestamp] - [callerCtx timestamp]) * 1000.0;
lwc_plog(runEnv, "%s performOnMainThread[blockCopy]: latency = %.3lf ms. Calling: [%s]",
[callerCtx identifier], latencyMs, aSelector);
lwc_plog(runEnv, "%s performOnMainThread[blockCopy]: latency = %.5lf ms. Calling: [%s]",
[callerCtx identifier], latencyMs, aSelector);
if ([runCtx callStack] != nil) {
lwc_plog(runEnv, "%s performOnMainThread[blockCopy]: run stack:\n%s",
[callerCtx identifier], toCString([runCtx callStack]));
if ([runCtx callStack] != nil) {
lwc_plog(runEnv, "%s performOnMainThread[blockCopy]: run stack:\n%s",
[callerCtx identifier], toCString([runCtx callStack]));
}
}
}
const CFTimeInterval start = (enableTracing) ? CACurrentMediaTime() : 0.0;
@@ -439,10 +462,12 @@ AWT_ASSERT_APPKIT_THREAD;
setBlockingEventDispatchThread(NO);
}
if (enableTracing) {
const double elapsedMs = (CACurrentMediaTime() - start) * 1000.0;
if (elapsedMs > mtThreshold) {
lwc_plog(runEnv, "%s performOnMainThread[blockCopy]: time = %.3lf ms. Caller=[%s]",
[callerCtx identifier], elapsedMs, toCString([callerCtx caller]));
if (enableTracingLog) {
const double elapsedMs = (CACurrentMediaTime() - start) * 1000.0;
if (elapsedMs > mtThreshold) {
lwc_plog(runEnv, "%s performOnMainThread[blockCopy]: time = %.5lf ms. Caller=[%s]",
[callerCtx identifier], elapsedMs, toCString([callerCtx caller]));
}
}
[callerCtx release];
@@ -455,7 +480,7 @@ AWT_ASSERT_APPKIT_THREAD;
if (invokeDirect) {
[ThreadUtilities invokeBlockCopy:blockCopy];
} else {
if (enableTracing) {
if (enableTracingLog) {
lwc_plog(env, "%s performOnMainThread[caller]: waiting on MainThread(%s). Caller=[%s] [%s]",
[callerCtx identifier], aSelector, toCString([callerCtx caller]),
wait ? "WAIT" : "ASYNC");
@@ -463,7 +488,7 @@ AWT_ASSERT_APPKIT_THREAD;
[ThreadUtilities performSelectorOnMainThread:@selector(invokeBlockCopy:) withObject:blockCopy waitUntilDone:wait modes:runLoopModes];
if (enableTracing) {
if (enableTracingLog) {
lwc_plog(env, "%s performOnMainThread[caller]: finished on MainThread(%s). Caller=[%s] [DONE]",
[callerCtx identifier], aSelector, toCString([callerCtx caller]));
}
@@ -480,7 +505,7 @@ AWT_ASSERT_APPKIT_THREAD;
return JavaRunLoopMode;
}
+ (NSMutableDictionary*) threadContextStore {
+ (NSMutableDictionary*)threadContextStore {
static NSMutableDictionary<NSString*, ThreadTraceContext*>* _threadTraceContextPerName;
static dispatch_once_t oncePredicate;
@@ -491,7 +516,7 @@ AWT_ASSERT_APPKIT_THREAD;
return _threadTraceContextPerName;
}
+ (ThreadTraceContext*) getTraceContext {
+ (ThreadTraceContext*)getTraceContext {
const NSString* thName = [[NSThread currentThread] name];
NSMutableDictionary* allContexts = [ThreadUtilities threadContextStore];
@@ -513,19 +538,19 @@ AWT_ASSERT_APPKIT_THREAD;
[[ThreadUtilities threadContextStore] removeObjectForKey:thName];
}
+ (void) resetTraceContext {
+ (void)resetTraceContext {
[[ThreadUtilities getTraceContext] reset];
}
+ (ThreadTraceContext*) recordTraceContext {
+ (ThreadTraceContext*)recordTraceContext {
return [ThreadUtilities recordTraceContext:@"recordTraceContext"];
}
+ (ThreadTraceContext*) recordTraceContext:(NSString*) prefix {
+ (ThreadTraceContext*)recordTraceContext:(NSString*) prefix {
return [ThreadUtilities recordTraceContext:prefix actionId:-1 useJavaModes:NO operation:""];
}
+ (ThreadTraceContext*) recordTraceContext:(NSString*) prefix
+ (ThreadTraceContext*)recordTraceContext:(NSString*) prefix
actionId:(long) actionId
useJavaModes:(BOOL) useJavaModes
operation:(char*) operation
@@ -540,6 +565,218 @@ AWT_ASSERT_APPKIT_THREAD;
return [thCtx set:actionId operation:operation useJavaModes:useJavaModes caller:caller callstack:callStack];
}
+ (NSString*)getThreadTraceContexts
{
NSMutableDictionary* allContexts = [ThreadUtilities threadContextStore];
// CHECK LEAK ?
NSMutableString* dump = [[[NSMutableString alloc] initWithCapacity:4096] autorelease];
[dump appendString:@"[\n"];
for (NSString* thName in allContexts) {
ThreadTraceContext *thCtx = allContexts[thName];
[dump appendString:@"\n["];
[dump appendFormat:@"\n thread:'%@'", thName];
[dump appendString:@"\n traceContext: "];
if (thCtx == nil) {
[dump appendString:@"null"];
} else {
[dump appendString:@"["];
[dump appendFormat:@"\n %@", thCtx.description];
[dump appendString:@"\n ]"];
}
[dump appendString:@"\n] \n"];
}
[dump appendString:@"]"];
[dump retain];
return dump;
}
+ (BOOL)isWithinPowerTransition {
if (wakeUpTime != 0LL) {
// check last wake-up time:
if (nowNearTime("wake-up", &wakeUpTime)) {
return true;
}
// reset invalid time:
wakeUpTime = 0LL;
} else if (sleepTime != 0LL) {
// check last sleep time:
if (nowNearTime("sleep", &sleepTime)) {
return true;
}
// reset invalid time:
sleepTime = 0LL;
} else if (TRACE_PWM) {
NSLog(@"EAWT: isWithinPowerTransition: no times");
}
return false;
}
+ (void)_systemOrScreenWillSleep:(NSNotification*)notification {
atomic_uint_least64_t now;
if (nanoUpTime(&now))
{
// keep most-recent wake-up time (system or display):
sleepTime = now;
if (TRACE_PWM_EVENTS) {
NSLog(@"EAWT: _systemOrScreenWillSleep[%@]: sleep time = %.5lf (%.5lf)",
[notification name], 1e-9 * sleepTime,
[NSProcessInfo processInfo].systemUptime);
}
// reset wake-up time (system or display):
wakeUpTime = 0LL;
if (TRACE_CLOCKS) {
dumpClocks();
}
}
}
+ (void)_systemOrScreenDidWake:(NSNotification*)notification {
atomic_uint_least64_t now;
if (nanoUpTime(&now))
{
// keep most-recent wake-up time (system or display):
wakeUpTime = now;
if (TRACE_PWM_EVENTS) {
NSLog(@"EAWT: _systemOrScreenDidWake[%@]: wake-up time = %.5lf (%.5lf)",
[notification name], 1e-9 * wakeUpTime,
[NSProcessInfo processInfo].systemUptime);
}
// CHECK
if (sleepTime != 0LL) {
if (now > sleepTime) {
// check last sleep time:
now -= sleepTime; // delta in ns
if (TRACE_PWM_EVENTS) {
NSLog(@"EAWT: _systemOrScreenDidWake: SLEEP duration = %.5lf ms", 1e-6 * now);
}
}
}
if (TRACE_CLOCKS) {
dumpClocks();
}
}
}
+ (BOOL)nanoUpTime:(atomic_uint_least64_t*)nanotime {
return nanoUpTime(nanotime);
}
+ (BOOL)nowNearTime:(NSString*)src refTime:(atomic_uint_least64_t*)refTime {
return nowNearTime(src.UTF8String, refTime);
}
bool nowNearTime(const char* src, atomic_uint_least64_t *refTime) {
if (*refTime != 0LL) {
atomic_uint_least64_t now;
if (nanoUpTime(&now)) {
if (now < *refTime) {
// should not happen with monotonic clocks, but:
now = *refTime;
}
// check absolute delta in nanoseconds:
now -= *refTime;
if (TRACE_PWM) {
NSLog(@"EAWT: nowNearTime[%s]: delta time = %.5lf ms", src, 1e-6 * now);
}
return (now <= RDV_PERIOD);
}
}
return false;
}
bool nanoUpTime(atomic_uint_least64_t *nanotime) {
// Use a monotonic clock (linearly increasing by each tick)
// but not counting the time while sleeping.
// NOTE:CLOCK_UPTIME_RAW seems counting more elapsed time
// arround sleep/wake-up cycle than CLOCK_PROCESS_CPUTIME_ID (adopted):
return getTime_nanos(CLOCK_PROCESS_CPUTIME_ID, nanotime);
}
bool getTime_nanos(clockid_t clock_id, atomic_uint_least64_t *nanotime) {
struct timespec tp;
// Use the given clock:
int status = clock_gettime(clock_id, &tp);
if (status != 0) {
return false;
}
*nanotime = tp.tv_sec * NANOS_PER_SEC + tp.tv_nsec;
return true;
}
void dumpClocks() {
if (TRACE_CLOCKS) {
logTime_nanos(CLOCK_REALTIME);
logTime_nanos(CLOCK_MONOTONIC);
logTime_nanos(CLOCK_MONOTONIC_RAW);
logTime_nanos(CLOCK_MONOTONIC_RAW_APPROX);
logTime_nanos(CLOCK_UPTIME_RAW);
logTime_nanos(CLOCK_UPTIME_RAW_APPROX);
logTime_nanos(CLOCK_PROCESS_CPUTIME_ID);
logTime_nanos(CLOCK_THREAD_CPUTIME_ID);
}
}
void logTime_nanos(clockid_t clock_id) {
if (TRACE_CLOCKS) {
atomic_uint_least64_t now;
if (getTime_nanos(clock_id, &now)) {
const char *clock_name;
switch (clock_id) {
case CLOCK_REALTIME:
clock_name = "CLOCK_REALTIME";
break;
case CLOCK_MONOTONIC:
clock_name = "CLOCK_MONOTONIC";
break;
case CLOCK_MONOTONIC_RAW:
clock_name = "CLOCK_MONOTONIC_RAW";
break;
case CLOCK_MONOTONIC_RAW_APPROX:
clock_name = "CLOCK_MONOTONIC_RAW_APPROX";
break;
case CLOCK_UPTIME_RAW:
clock_name = "CLOCK_UPTIME_RAW";
break;
case CLOCK_UPTIME_RAW_APPROX:
clock_name = "CLOCK_UPTIME_RAW_APPROX";
break;
case CLOCK_PROCESS_CPUTIME_ID:
clock_name = "CLOCK_PROCESS_CPUTIME_ID";
break;
case CLOCK_THREAD_CPUTIME_ID:
clock_name = "CLOCK_THREAD_CPUTIME_ID";
break;
default:
clock_name = "unknown";
}
NSLog(@"EAWT: logTime_nanos[%27s] time: %.6lf s", clock_name, 1e-9 * now);
}
}
}
+ (void)registerForSystemAndScreenNotifications {
static BOOL notificationRegistered = false;
if (!notificationRegistered) {
notificationRegistered = true;
NSNotificationCenter *ctr = [[NSWorkspace sharedWorkspace] notificationCenter];
Class clz = [ThreadUtilities class];
[ctr addObserver:clz selector:@selector(_systemOrScreenWillSleep:) name:NSWorkspaceWillSleepNotification object:nil];
[ctr addObserver:clz selector:@selector(_systemOrScreenDidWake:) name:NSWorkspaceDidWakeNotification object:nil];
[ctr addObserver:clz selector:@selector(_systemOrScreenWillSleep:) name:NSWorkspaceScreensDidSleepNotification object:nil];
[ctr addObserver:clz selector:@selector(_systemOrScreenDidWake:) name:NSWorkspaceScreensDidWakeNotification object:nil];
}
}
@end
void OSXAPP_SetJavaVM(JavaVM *vm)
@@ -703,9 +940,10 @@ JNIEXPORT void lwc_plog(JNIEnv* env, const char *formatMsg, ...) {
timestamp, actionId, operation]);
}
- (NSString *)getDescription {
return [NSString stringWithFormat:@"%s useJavaModes=%d sleep=%d caller=[%@]",
[self identifier], useJavaModes, sleep, caller];
- (NSString *)description {
// creates autorelease string:
return [NSString stringWithFormat:@"%s useJavaModes=%d sleep=%d caller=[%@] callStack={\n%@}",
[self identifier], useJavaModes, sleep, caller, callStack];
}
@end

View File

@@ -902,12 +902,13 @@ AwtFileDialog::Show(void *p)
DWORD dwFlags;
OLE_HRT(pfd->GetOptions(&dwFlags));
dwFlags |= FOS_FORCEFILESYSTEM;
if (multipleMode == JNI_TRUE) {
dwFlags |= FOS_ALLOWMULTISELECT;
}
if (folderPickerMode) {
dwFlags |= FOS_PICKFOLDERS;
} else {
dwFlags |= FOS_FORCEFILESYSTEM; // Windows bug: in the folder picker mode, it prevents the "Linux" node from appearing
}
OLE_HRT(pfd->SetOptions(dwFlags));

View File

@@ -53,6 +53,7 @@ compiler/ciReplay/TestInliningProtectionDomain.java NOBUG generic-all
compiler/ciReplay/TestLambdas.java 8300210 generic-all
compiler/ciReplay/TestServerVM.java 8300210 generic-all
compiler/ciReplay/TestUnresolvedClasses.java NOBUG generic-all
compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java JBR-8185 windows-x64
#############################################################################

View File

@@ -40,24 +40,25 @@
# gtest
gtest/AsyncLogGtest.java initial_run generic-all
gtest/MetaspaceGtests.java#reclaim-none-ndebug initial_run generic-all
gtest/LargePageGtests.java#use-large-pages-sysV initial_run linux-all
gtest/LargePageGtests.java#use-large-pages-1G initial_run linux-all
gtest/GTestWrapper.java initial_run generic-all
gtest/MetaspaceUtilsGtests.java initial_run generic-all
gtest/MetaspaceGtests.java#balanced-no-ccs initial_run generic-all
gtest/MetaspaceGtests.java#balanced-with-guards JBR-5718 generic-all
gtest/MetaspaceGtests.java#default-debug JBR-5718 generic-all
gtest/MetaspaceGtests.java#reclaim-aggressive-debug JBR-5718 generic-all
gtest/MetaspaceGtests.java#reclaim-none-debug JBR-5718 generic-all
gtest/MetaspaceGtests.java#reclaim-aggressive-ndebug initial_run generic-all
gtest/LargePageGtests.java#use-large-pages initial_run linux-all,windows-all
gtest/AsyncLogGtest.java JBR-4027 generic-all
gtest/GTestWrapper.java JBR-4027 generic-all
gtest/MetaspaceGtests.java#balanced-no-ccs JBR-4027 generic-all
gtest/MetaspaceGtests.java#balanced-with-guards JBR-4027 generic-all
gtest/MetaspaceGtests.java#default-debug JBR-4027 generic-all
gtest/MetaspaceGtests.java#reclaim-aggressive-debug JBR-4027 generic-all
gtest/MetaspaceGtests.java#reclaim-aggressive-ndebug JBR-4027 generic-all
gtest/MetaspaceGtests.java#reclaim-none-debug JBR-4027 generic-all
gtest/MetaspaceGtests.java#reclaim-none-ndebug JBR-4027 generic-all
gtest/MetaspaceUtilsGtests.java JBR-4027 generic-all
gtest/LargePageGtests.java#use-large-pages JBR-4027 linux-all,windows-all
gtest/LargePageGtests.java#use-large-pages-sysV JBR-4027 linux-all
gtest/LargePageGtests.java#use-large-pages-1G JBR-4027 linux-all
gtest/NativeHeapTrimmerGtest.java JBR-5718 generic-all
gtest/NMTGtests.java#nmt-detail JBR-5718 generic-all
gtest/NMTGtests.java#nmt-off JBR-5718 generic-all
gtest/NMTGtests.java#nmt-summary JBR-5718 generic-all
gtest/NativeHeapTrimmerGtest.java JBR-4027 generic-all
gtest/NMTGtests.java#nmt-detail JBR-4027 generic-all
gtest/NMTGtests.java#nmt-off JBR-4027 generic-all
gtest/NMTGtests.java#nmt-summary JBR-4027 generic-all
gtest/WindowsProcessorGroups.java JBR-4027 generic-all
gc/stress/TestReclaimStringsLeaksMemory.java initial_run windows-all
@@ -152,6 +153,7 @@ runtime/os/TestTracePageSizes.java#compiler-options 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#G1 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#Parallel 8267460 linux-aarch64
runtime/os/TestTracePageSizes.java#Serial 8267460 linux-aarch64
runtime/os/windows/TestAvailableProcessors.java JBR-8182 windows-all
runtime/ErrorHandling/CreateCoredumpOnCrash.java 8267433,initial_run macosx-x64,windows-aarch64
runtime/CompressedOops/CompressedClassPointers.java 8305765 generic-all
runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all

View File

@@ -873,6 +873,7 @@ jdk_awt_wayland = \
-java/awt/event/KeyEvent/KeyTyped/CtrlSpace.java \
-java/awt/event/KeyEvent/KeyTyped/DeleteKeyTyped.java \
-java/awt/event/KeyEvent/KeyTyped/EscapeKeyTyped.java \
-java/awt/event/KeyEvent/KeyTyped/Numpad1KeyTyped.java \
-java/awt/event/KeyEvent/RobotCrash/RobotCrash.java \
-java/awt/event/KeyEvent/ShiftF10Test.java \
-java/awt/event/KeyEvent/SwallowKeyEvents/SwallowKeyEvents.java \

View File

@@ -30,14 +30,18 @@ import java.io.InputStreamReader;
/**
* @test
* @summary VerifyDependencies checks readability verifies that a Linux shared
* library has no dependency on symbols from glibc version higher than 2.28
* library has no dependency on symbols from glibc version higher than <code>expectedVersion</code>
* @run main VerifyDependencies
* @requires (os.family == "linux")
*/
public class VerifyDependencies {
static final public String EXPECTED_VERSION = "2.28";
static final public String EXPECTED_VERSION_LEGACY = "2.17";
static final public String EXPECTED_VERSION_VULKAN = "2.28";
static String expectedVersion;
public static void verifyLibrary(String libraryPath) throws IOException {
Process process;
BufferedReader reader;
@@ -52,12 +56,12 @@ public class VerifyDependencies {
System.out.println(line);
if (line.contains("GLIBC_")) {
String version = extractVersion(line);
if (compareVersions(version, EXPECTED_VERSION) > 0) {
if (compareVersions(version, expectedVersion) > 0) {
throw new RuntimeException(libraryPath + " has a dependency on glibc version " + version);
}
}
}
System.out.println(libraryPath + " has no dependency on glibc version higher than " + EXPECTED_VERSION);
System.out.println(libraryPath + " has no dependency on glibc version higher than " + expectedVersion);
}
private static String extractVersion(String line) {
@@ -125,6 +129,12 @@ public class VerifyDependencies {
public static void main(String[] args) throws IOException {
String javaHome = System.getProperty("java.home");
String vendorVersion = System.getProperty("java.vendor.version");
expectedVersion = vendorVersion.substring(Math.max(vendorVersion.length() - 3, 0)).compareTo("-vk") == 0
? EXPECTED_VERSION_VULKAN : EXPECTED_VERSION_LEGACY;
System.out.println("supporting glibc version is not less than " + expectedVersion);
findInDirectory(javaHome + "/bin", false);
findInDirectory(javaHome + "/lib", true);
}

View File

@@ -1,3 +1,4 @@
java/awt/FullScreen/SetFullScreenTest.java JBR-8184 macosx-aarch64
java/awt/Graphics2D/DrawPrimitivesTest.java JBR-5620 macosx-aarch64
java/awt/image/multiresolution/MultiresolutionIconTest.java JBR-7146 macosx-12.7.4,macosx-12.7.5,macosx-12.7.6
java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java JBR-7146 macosx-12.7.4,macosx-12.7.5,macosx-12.7.6

View File

@@ -279,6 +279,7 @@ java/awt/event/KeyEvent/KeyTyped/AltShiftEnterShouldNotSendKeyTyped7157.java JBR
java/awt/event/KeyEvent/KeyTyped/CtrlASCII.java JBR-4880 windows-all
java/awt/event/KeyEvent/KeyTyped/CtrlSpace.java JBR-3817 windows-all,macosx-all
java/awt/event/KeyEvent/KeyTyped/Numpad1KeyTyped.java JBR-7912 windows-all
java/awt/dnd/BadSerializationTest/BadSerializationTest.java linux-x64,windows-x64
java/awt/dnd/Button2DragTest/Button2DragTest.java 8310490 linux-all
@@ -1337,6 +1338,9 @@ javax/swing/JTable/JTableOrientationNavTest/JTableOrientationNavTest.java JBR-68
javax/swing/text/CSSBorder/6796710/bug6796710.java JBR-6465 windows-all,linux-aarch64
javax/swing/text/FlowView/LayoutTest.java JBR-4880 windows-all
javax/swing/text/html/7189299/bug7189299.java JBR-4880 windows-all
jb/java/awt/wayland/RobotGetOOBPixelsTest.java JBR-8029 linux-5.18.2-arch1-1
jb/java/awt/wayland/RobotGetPixelTest.java JBR-8029 linux-5.18.2-arch1-1
jb/java/awt/wayland/RobotGetPixelsTest.java JBR-8029 linux-5.18.2-arch1-1
jb/java/jcef/HandleJSQueryTest3314.sh JBR-4866 linux-all
jb/java/jcef/HwFacadeWindowNoFrontTest.java

View File

@@ -1,3 +1,7 @@
jb/java/awt/wayland/RobotGetOOBPixelsTest.java JBR-8029 linux-all
jb/java/awt/wayland/RobotGetPixelTest.java JBR-8029 linux-all
jb/java/awt/wayland/RobotGetPixelsTest.java JBR-8029 linux-all
# Fedora & ArchLinux (Wayland) & Ubuntu 21.04
java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.java 8279256 linux-all
java/awt/event/KeyEvent/FunctionKeyTest.java JBR-7773 linux-all