in skiko/src/awtMain/objectiveC/macos/MetalRedrawer.mm [121:177]
JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MetalRedrawer_createMetalDevice(
JNIEnv *env, jobject redrawer, jlong windowPtr, jboolean transparency, jint frameBuffering, jlong adapterPtr, jlong platformInfoPtr)
{
@autoreleasepool {
id<MTLDevice> adapter = (__bridge id<MTLDevice>) (void *) adapterPtr;
MetalDevice *device = [MetalDevice new];
NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers> *) (void*) platformInfoPtr;
CALayer *container = [dsi_mac windowLayer];
[container removeAllAnimations];
[container setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
[container setNeedsDisplayOnBoundsChange: YES];
AWTMetalLayer *layer = [AWTMetalLayer new];
if (frameBuffering == 2 || frameBuffering == 3) {
layer.maximumDrawableCount = frameBuffering;
}
[container addSublayer: layer];
layer.javaRef = env->NewGlobalRef(redrawer);
id<MTLCommandQueue> fQueue = [MTLCommandQueueCache.sharedCache commandQueueForDevice:adapter];
device.container = container;
device.layer = layer;
device.adapter = adapter;
device.queue = fQueue;
device.layer.device = device.adapter;
device.layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
device.layer.contentsGravity = kCAGravityTopLeft;
CGFloat transparent[] = { 0.0f, 0.0f, 0.0f, 0.0f };
device.layer.backgroundColor = CGColorCreate(CGColorSpaceCreateDeviceRGB(), transparent);
device.layer.opaque = NO;
device.layer.framebufferOnly = NO;
/// max inflight command buffers count matches swapchain size to avoid overcommitment
device.inflightSemaphore = dispatch_semaphore_create(device.layer.maximumDrawableCount);
NSWindow* window = (__bridge NSWindow*) (void *) windowPtr;
jmethodID onOcclusionStateChanged = getOnOcclusionStateChangedMethodID(env, redrawer);
device.occlusionObserver =
[[NSNotificationCenter defaultCenter] addObserverForName:NSWindowDidChangeOcclusionStateNotification
object:window
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * _Nonnull note) {
BOOL isOccluded = ([window occlusionState] & NSWindowOcclusionStateVisible) == 0;
JNIEnv *jniEnv = resolveJNIEnvForCurrentThread();
jniEnv->CallObjectMethod(layer.javaRef, onOcclusionStateChanged, isOccluded);
}];
return (jlong) (__bridge_retained void *) device;
}
}