Compare commits

...

2 Commits

Author SHA1 Message Date
Vitaly Provodin
73cb3fb813 update exclude list on results of 21.0.4_b607.1 test runs 2024-09-23 12:41:52 +04:00
Alexey Ushakov
cc7ea05b92 JBR-7588 Metal: Reuse MTLContext for all GCs of the same GPU
Implemented reference counting for shared MTLContext objects. Supported multiple display links per MTLContext. Also, works for macOS version < 10.13
2024-09-21 03:18:20 +04:00
9 changed files with 169 additions and 62 deletions

View File

@@ -85,10 +85,13 @@
@property jboolean useMaskColor;
@property (readonly, strong) id<MTLDevice> device;
@property (readonly) NSString* shadersLib;
@property (strong) id<MTLCommandQueue> commandQueue;
@property (strong) id<MTLCommandQueue> blitCommandQueue;
@property (strong) id<MTLBuffer> vertexBuffer;
@property (readonly) NSMutableDictionary<NSNumber*, NSValue*>* displayLinks;
@property (readonly) EncoderManager * encoderManager;
@property (readonly) MTLSamplerManager * samplerManager;
@property (readonly) MTLStencilManager * stencilManager;
@@ -106,10 +109,13 @@
*/
+ (MTLContext*) setSurfacesEnv:(JNIEnv*)env src:(jlong)pSrc dst:(jlong)pDst;
- (id)initWithDevice:(jint)displayID shadersLib:(NSString*)shadersLib;
+ (NSMutableDictionary*) contextStore;
+ (MTLContext*) createContextWithDeviceIfAbsent:(jint)displayID shadersLib:(NSString*)mtlShadersLib;
- (id)initWithDevice:(id<MTLDevice>)device display:(jint) displayID shadersLib:(NSString*)mtlShadersLib;
- (void)dealloc;
- (void)handleDisplayLink: (BOOL)enabled source:(const char*)src;
- (void)handleDisplayLink:(BOOL)enabled display:(jint)display source:(const char*)src;
- (void)createDisplayLinkIfAbsent: (jint)displayID;
/**
* Resets the current clip state (disables both scissor and depth tests).

View File

@@ -72,7 +72,11 @@ static struct TxtVertex verts[PGRAM_VERTEX_COUNT] = {
{{-1.0, 1.0}, {0.0, 0.0}}
};
MTLTransform* tempTransform = nil;
typedef struct {
jint displayID;
CVDisplayLinkRef displayLink;
MTLContext* mtlc;
} DLParams;
@implementation MTLCommandBufferWrapper {
id<MTLCommandBuffer> _commandBuffer;
@@ -134,7 +138,6 @@ MTLTransform* tempTransform = nil;
@implementation MTLContext {
MTLCommandBufferWrapper * _commandBufferWrapper;
CVDisplayLinkRef _displayLink;
NSMutableSet* _layers;
int _displayLinkCount;
CFTimeInterval _lastRedrawTime;
@@ -153,34 +156,101 @@ MTLTransform* tempTransform = nil;
@synthesize textureFunction,
vertexCacheEnabled, aaEnabled, useMaskColor,
device, pipelineStateStorage,
device, shadersLib, pipelineStateStorage,
commandQueue, blitCommandQueue, vertexBuffer,
texturePool, paint=_paint, encoderManager=_encoderManager,
samplerManager=_samplerManager, stencilManager=_stencilManager;
extern void initSamplers(id<MTLDevice> device);
- (id)initWithDevice:(jint)displayID shadersLib:(NSString*)shadersLib {
+ (NSMutableDictionary*) contextStore {
static NSMutableDictionary<NSNumber*, MTLContext*> *_contextStore;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_contextStore = [[NSMutableDictionary alloc] init];
});
return _contextStore;
}
+ (MTLContext*) createContextWithDeviceIfAbsent:(jint)displayID shadersLib:(NSString*)mtlShadersLib {
// Initialization code here.
id<MTLDevice> device = CGDirectDisplayCopyCurrentMetalDevice(displayID);
if (device == nil) {
J2dRlsTraceLn1(J2D_TRACE_ERROR, "MTLContext_createContextWithDeviceIfAbsent(): Cannot create device from "
"displayID=%d", displayID)
// Fallback to the default metal device for main display
jint mainDisplayID = CGMainDisplayID();
if (displayID == mainDisplayID) {
device = MTLCreateSystemDefaultDevice();
}
if (device == nil) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_createContextWithDeviceIfAbsent(): Cannot fallback to default "
"metal device")
return nil;
}
}
id<NSCopying> devID = nil;
if (@available(macOS 10.13, *)) {
devID = @(device.registryID);
} else {
devID = device.name;
}
MTLContext* mtlc = MTLContext.contextStore[devID];
if (mtlc == nil) {
mtlc = [[MTLContext alloc] initWithDevice:device display:displayID shadersLib:mtlShadersLib];
if (mtlc != nil) {
MTLContext.contextStore[devID] = 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)
}
} 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])
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)
}
[mtlc createDisplayLinkIfAbsent:displayID];
return mtlc;
}
+ (void) releaseContext:(MTLContext*) mtlc {
id<NSCopying> devID = nil;
if (@available(macOS 10.13, *)) {
devID = @(mtlc.device.registryID);
} else {
devID = mtlc.device.name;
}
MTLContext* ctx = MTLContext.contextStore[devID];
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];
J2dRlsTraceLn1(J2D_TRACE_INFO, "MTLContext_releaseContext: dealloc context(%p)", mtlc);
}
}
}
- (id)initWithDevice:(id<MTLDevice>)mtlDevice display:(jint) displayID shadersLib:(NSString*)mtlShadersLib {
self = [super init];
if (self) {
// Initialization code here.
device = CGDirectDisplayCopyCurrentMetalDevice(displayID);
if (device == nil) {
J2dRlsTraceLn1(J2D_TRACE_ERROR, "MTLContext.initWithDevice(): Cannot create device from displayID=%d",
displayID);
// Fallback to the default metal device for main display
jint mainDisplayID = CGMainDisplayID();
if (displayID == mainDisplayID) {
device = MTLCreateSystemDefaultDevice();
}
if (device == nil) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext.initWithDevice(): Cannot fallback to default metal device");
return nil;
}
}
device = mtlDevice;
shadersLib = [[NSString alloc] initWithString:mtlShadersLib];
pipelineStateStorage = [[MTLPipelineStatesStorage alloc] initWithDevice:device shaderLibPath:shadersLib];
if (pipelineStateStorage == nil) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext.initWithDevice(): Failed to initialize MTLPipelineStatesStorage.");
@@ -213,25 +283,8 @@ extern void initSamplers(id<MTLDevice> device);
_displayLinkCount = 0;
_lastRedrawTime = 0.0;
if (isDisplaySyncEnabled()) {
_displayLinks = [[NSMutableDictionary alloc] init];
_layers = [[NSMutableSet alloc] init];
if (TRACE_CVLINK) {
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_CVDisplayLinkCreateWithCGDisplay: "
"ctx=%p displayID=%d", self, displayID);
}
CHECK_CVLINK("CreateWithCGDisplay",
CVDisplayLinkCreateWithCGDisplay(displayID, &_displayLink));
if (_displayLink == nil) {
J2dRlsTraceLn(J2D_TRACE_ERROR,
"MTLContext.initWithDevice(): Failed to initialize CVDisplayLink.");
return nil;
} else {
CHECK_CVLINK("SetOutputCallback", CVDisplayLinkSetOutputCallback(
_displayLink,
&mtlDisplayLinkCallback,
(__bridge void *) self));
}
} else {
_displayLink = nil;
}
_glyphCacheLCD = [[MTLGlyphCache alloc] initWithContext:self];
_glyphCacheAA = [[MTLGlyphCache alloc] initWithContext:self];
@@ -239,13 +292,47 @@ extern void initSamplers(id<MTLDevice> device);
return self;
}
- (void)handleDisplayLink: (BOOL)enabled source:(const char*)src {
if (_displayLink == nil) {
- (void)createDisplayLinkIfAbsent: (jint)displayID {
if (isDisplaySyncEnabled() && _displayLinks[@(displayID)] == nil) {
CVDisplayLinkRef _displayLink;
if (TRACE_CVLINK) {
J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_createDisplayLinkIfAbsent: "
"ctx=%p displayID=%d", self, displayID);
}
CHECK_CVLINK("CreateWithCGDisplay",
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", CVDisplayLinkSetOutputCallback(
_displayLink,
&mtlDisplayLinkCallback,
(__bridge DLParams*) dlParams));
}
}
}
- (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 - displayLink = nil", src, self);
"ctx=%p - displayLinks = nil", src, self);
}
} 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;
}
DLParams *dlParams = [dlParamsVal pointerValue];
CVDisplayLinkRef _displayLink = dlParams->displayLink;
if (enabled) {
if (!CVDisplayLinkIsRunning(_displayLink)) {
CHECK_CVLINK("Start", CVDisplayLinkStart(_displayLink));
@@ -269,10 +356,11 @@ extern void initSamplers(id<MTLDevice> device);
- (void)dealloc {
J2dTraceLn(J2D_TRACE_INFO, "MTLContext.dealloc");
if (_displayLink != nil) {
if (_displayLinks != nil) {
[self haltRedraw];
}
[shadersLib release];
// TODO : Check that texturePool is completely released.
// texturePool content is released in MTLCommandBufferWrapper.onComplete()
//self.texturePool = nil;
@@ -627,7 +715,7 @@ extern void initSamplers(id<MTLDevice> device);
}
}
- (void) redraw {
- (void) redraw:(NSNumber*)displayIDNum {
AWT_ASSERT_APPKIT_THREAD;
/*
* Avoid repeated invocations by UIKit Main Thread
@@ -650,7 +738,7 @@ extern void initSamplers(id<MTLDevice> device);
if (_layers.count > 0) {
[_layers removeAllObjects];
}
[self handleDisplayLink:NO source:"redraw"];
[self handleDisplayLink:NO display:[displayIDNum integerValue] source:"redraw"];
}
}
@@ -658,8 +746,8 @@ CVReturn mtlDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp*
{
J2dTraceLn1(J2D_TRACE_VERBOSE, "MTLContext_mtlDisplayLinkCallback: ctx=%p", displayLinkContext);
@autoreleasepool {
MTLContext *ctx = (__bridge MTLContext *)displayLinkContext;
[ThreadUtilities performOnMainThread:@selector(redraw) on:ctx withObject:nil waitUntilDone:NO];
DLParams* dlParams = (__bridge DLParams* *)displayLinkContext;
[ThreadUtilities performOnMainThread:@selector(redraw:) on:dlParams->mtlc withObject:@(dlParams->displayID) waitUntilDone:NO];
}
return kCVReturnSuccess;
}
@@ -674,25 +762,25 @@ CVReturn mtlDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp*
// Request for redraw before starting display link to avoid rendering problem on M2 processor
[layer setNeedsDisplay];
}
[self handleDisplayLink:YES source:"startRedraw"];
[self handleDisplayLink:YES display:layer.displayID source:"startRedraw"];
}
- (void)stopRedraw:(MTLLayer*) layer {
AWT_ASSERT_APPKIT_THREAD;
J2dTraceLn2(J2D_TRACE_VERBOSE, "MTLContext_stopRedraw: ctx=%p layer=%p", self, layer);
if (_displayLink != nil) {
if (_displayLinks != nil) {
if (--layer.redrawCount <= 0) {
[_layers removeObject:layer];
layer.redrawCount = 0;
}
if ((_layers.count == 0) && (_displayLinkCount == 0)) {
[self handleDisplayLink:NO source:"stopRedraw"];
[self handleDisplayLink:NO display:layer.displayID source:"stopRedraw"];
}
}
}
- (void)haltRedraw {
if (_displayLink != nil) {
if (_displayLinks != nil) {
if (TRACE_CVLINK) {
J2dRlsTraceLn1(J2D_TRACE_VERBOSE, "MTLContext_haltRedraw: ctx=%p", self);
}
@@ -703,10 +791,16 @@ CVReturn mtlDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp*
[_layers removeAllObjects];
}
_displayLinkCount = 0;
[self handleDisplayLink:NO source:"haltRedraw"];
CVDisplayLinkRelease(_displayLink);
_displayLink = NULL;
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);
}
[_displayLinks release];
_displayLinks = NULL;
}
}

View File

@@ -45,6 +45,7 @@
*/
typedef struct _MTLGraphicsConfigInfo {
MTLContext *context;
jint displayID;
} MTLGraphicsConfigInfo;
#endif /* MTLGraphicsConfig_h_Included */

View File

@@ -48,7 +48,7 @@ MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo)
mtlinfo->context = nil;
[ThreadUtilities performOnMainThreadWaiting:NO block:^() {
if (mtlc != NULL) {
[mtlc release];
[MTLContext releaseContext:mtlc];
}
free(mtlinfo);
}];
@@ -92,7 +92,7 @@ JNI_COCOA_ENTER(env);
[ThreadUtilities performOnMainThreadWaiting:YES block:^() {
MTLContext* mtlc = [[MTLContext alloc] initWithDevice:displayID
MTLContext* mtlc = [MTLContext createContextWithDeviceIfAbsent:displayID
shadersLib:path];
if (mtlc != 0L) {
// create the MTLGraphicsConfigInfo record for this context
@@ -100,6 +100,7 @@ JNI_COCOA_ENTER(env);
if (mtlinfo != NULL) {
memset(mtlinfo, 0, sizeof(MTLGraphicsConfigInfo));
mtlinfo->context = mtlc;
mtlinfo->displayID = displayID;
} else {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: could not allocate memory for mtlinfo");
[mtlc release];

View File

@@ -34,6 +34,7 @@
@property (nonatomic) jobject javaLayer;
@property (readwrite, assign) MTLContext* ctx;
@property (readwrite, assign) NSInteger displayID;
@property (readwrite, assign) id<MTLTexture>* buffer;
@property (readwrite, assign) id<MTLTexture>* outBuffer;
@property (readwrite, atomic) int nextDrawableCount;

View File

@@ -554,6 +554,7 @@ Java_sun_java2d_metal_MTLLayer_validate
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;
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;

View File

@@ -1,3 +1,4 @@
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
java/awt/Paint/PaintNativeOnUpdate.java JBR-7146 macosx-12.7.4,macosx-12.7.5,macosx-12.7.6

View File

@@ -154,6 +154,7 @@ java/awt/Frame/8158918/SetExtendedState.java JBR-6408 linux-all
java/awt/Frame/GetGraphicsStressTest/GetGraphicsStressTest.java JBR-6509 generic-all
java/awt/Frame/MaximizedUndecorated/MaximizedUndecorated.java 8022302 generic-all
java/awt/Frame/MaximizedToIconified/MaximizedToIconified.java 8296972 macosx-all
java/awt/Frame/MaximizedToMaximized/MaximizedToMaximized.java 8340595 macosx-15.0
java/awt/Frame/MaximizedToOppositeScreen/MaximizedToOppositeScreenBig.java JBR-5303 windows-all
java/awt/Frame/RestoreToOppositeScreen/RestoreToOppositeScreen.java 8286840 linux-all
java/awt/dnd/AcceptDropMultipleTimes/AcceptDropMultipleTimes.java JBR-4880,JBR-6683 windows-all,linux-all
@@ -257,6 +258,7 @@ java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java JBR-4275,JB
java/awt/FullScreen/NoResizeEventOnDMChangeTest/NoResizeEventOnDMChangeTest.java 7188711,8253184 linux-all,windows-all
java/awt/FullScreen/UninitializedDisplayModeChangeTest/UninitializedDisplayModeChangeTest.java 7188711,8273617,JBR-4880,8253184 macosx-all,linux-all,windows-all
java/awt/Focus/8013611/JDK8013611.java 8175366 windows-all,macosx-all
java/awt/Focus/6401036/InputVerifierTest2.java JBR-7537 linux-aarch64
java/awt/Focus/6981400/Test1.java 8029675,JBR-5510 windows-all,macosx-all,linux-5.18.2-arch1-1
java/awt/Focus/6981400/Test3.java 8173264 generic-all
java/awt/Focus/8000326/SetFocusTraversalKeysEnabledTest.java JBR-4997,JBR-5729 windows-all,linux-all
@@ -356,7 +358,6 @@ sun/java2d/SunGraphics2D/DrawImageBilinear.java 8297175 linux-all
java/awt/Graphics2D/CopyAreaOOB.java JBR-5354 macosx-all,windows-all,linux-5.18.2-arch1-1
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
java/awt/Graphics2D/DrawString/TextRenderingTest.java JBR-4260 macosx-11.7.1
java/awt/Graphics2D/ScaledTransform/ScaledTransform.java 8277240 linux-all
sun/java2d/SunGraphics2D/PolyVertTest.java 6986565 generic-all
sun/java2d/SunGraphics2D/SimplePrimQuality.java 6992007 generic-all
@@ -389,6 +390,7 @@ java/awt/Frame/MiscUndecorated/ActiveSwingWindowTest.java JBR-5210 windows-all
java/awt/Frame/MiscUndecorated/FrameCloseTest.java JBR-5210 windows-all
java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244,JBR-5786 macosx-aarch64,generic-all
java/awt/Robot/HiDPIMouseClick/HiDPIRobotMouseClick.java 8253184 windows-all
java/awt/Robot/NonEmptyErrorStream.java 8340330,JBR-5510 macosx-15.0,linux-5.18.2-arch1-1
java/awt/Robot/RobotExtraButton/RobotExtraButton.java JBR-6554 linux-all
java/awt/Modal/FileDialog/FileDialogAppModal1Test.java 7186009,8253184 macosx-all,windows-all
java/awt/Modal/FileDialog/FileDialogAppModal2Test.java 7186009,8253184 macosx-all,windows-all
@@ -1441,7 +1443,6 @@ java/awt/Choice/ChoiceGeneratesItemEvents.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Choice/ChoiceStaysOpenedOnTAB.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Graphics/XORPaint.java#id2 JBR-5510 linux-5.18.2-arch1-1
java/awt/Robot/HiDPIScreenCapture/ScreenCaptureGtkTest.java JBR-5510 linux-5.18.2-arch1-1
java/awt/Robot/NonEmptyErrorStream.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JComboBox/TestComboBoxComponentRendering.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JMenu/TestDisabledMenuForegroundColor.java JBR-5510 linux-5.18.2-arch1-1
javax/swing/JPasswordField/TestSelectedTextBackgroundColor.java JBR-5510 linux-5.18.2-arch1-1

View File

@@ -54,6 +54,7 @@ java/awt/PopupMenu/PopupMenuLocation.java 8238720,JBR-5071 windows-all,macosx-al
java/awt/Window/AlwaysOnTop/SyncAlwaysOnTopFieldTest.java JBR-6845 linux-all
java/awt/Window/TopLevelLocation/TopLevelLocation.java JBR-5799 windows-all
java/awt/Window/WindowSizeDifferentScreens/WindowSizeDifferentScreens.java JBR-5513 linux-all
javax/swing/JComboBox/TestComboBoxComponentRendering.java JBR-6110 linux-x64
javax/swing/JComponent/7154030/bug7154030.java JBR-6134 windows-x64
javax/swing/JPopupMenu/6580930/bug6580930.java JBR-5071 linux-all
javax/swing/JSlider/6848475/bug6848475.java JBR-7329,JBR-7472 windows-all