1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #import "sun_java2d_metal_MTLGraphicsConfig.h" 27 28 #import "MTLGraphicsConfig.h" 29 #import "MTLSurfaceData.h" 30 #import "ThreadUtilities.h" 31 32 #import <stdlib.h> 33 #import <string.h> 34 #import <ApplicationServices/ApplicationServices.h> 35 #import <JavaNativeFoundation/JavaNativeFoundation.h> 36 37 #pragma mark - 38 #pragma mark "--- Mac OS X specific methods for GL pipeline ---" 39 40 /** 41 * Disposes all memory and resources associated with the given 42 * CGLGraphicsConfigInfo (including its native MTLContext data). 43 */ 44 void 45 MTLGC_DestroyMTLGraphicsConfig(jlong pConfigInfo) 46 { 47 J2dTraceLn(J2D_TRACE_INFO, "MTLGC_DestroyMTLGraphicsConfig"); 48 49 MTLGraphicsConfigInfo *mtlinfo = 50 (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo); 51 if (mtlinfo == NULL) { 52 J2dRlsTraceLn(J2D_TRACE_ERROR, 53 "MTLGC_DestroyMTLGraphicsConfig: info is null"); 54 return; 55 } 56 57 MTLContext *mtlc = (MTLContext*)mtlinfo->context; 58 if (mtlc != NULL) { 59 [mtlinfo->context release]; 60 mtlinfo->context = nil; 61 } 62 free(mtlinfo); 63 } 64 65 #pragma mark - 66 #pragma mark "--- MTLGraphicsConfig methods ---" 67 68 69 /** 70 * Attempts to initialize CGL and the core OpenGL library. 71 */ 72 JNIEXPORT jboolean JNICALL 73 Java_sun_java2d_metal_MTLGraphicsConfig_initMTL 74 (JNIEnv *env, jclass cglgc) 75 { 76 J2dRlsTraceLn(J2D_TRACE_INFO, "MTLGraphicsConfig_initMTL"); 77 78 if (!MTLFuncs_OpenLibrary()) { 79 return JNI_FALSE; 80 } 81 82 if (!MTLFuncs_InitPlatformFuncs() || 83 !MTLFuncs_InitBaseFuncs() || 84 !MTLFuncs_InitExtFuncs()) 85 { 86 MTLFuncs_CloseLibrary(); 87 return JNI_FALSE; 88 } 89 90 return JNI_TRUE; 91 } 92 93 94 /** 95 * Determines whether the CGL pipeline can be used for a given GraphicsConfig 96 * provided its screen number and visual ID. If the minimum requirements are 97 * met, the native CGLGraphicsConfigInfo structure is initialized for this 98 * GraphicsConfig with the necessary information (pixel format, etc.) 99 * and a pointer to this structure is returned as a jlong. If 100 * initialization fails at any point, zero is returned, indicating that CGL 101 * cannot be used for this GraphicsConfig (we should fallback on an existing 102 * 2D pipeline). 103 */ 104 JNIEXPORT jlong JNICALL 105 Java_sun_java2d_metal_MTLGraphicsConfig_getMTLConfigInfo 106 (JNIEnv *env, jclass cglgc, jint displayID, jstring mtlShadersLib) 107 { 108 jlong ret = 0L; 109 JNF_COCOA_ENTER(env); 110 NSMutableArray * retArray = [NSMutableArray arrayWithCapacity:3]; 111 [retArray addObject: [NSNumber numberWithInt: (int)displayID]]; 112 [retArray addObject: [NSString stringWithUTF8String: JNU_GetStringPlatformChars(env, mtlShadersLib, 0)]]; 113 if ([NSThread isMainThread]) { 114 [MTLGraphicsConfigUtil _getMTLConfigInfo: retArray]; 115 } else { 116 [MTLGraphicsConfigUtil performSelectorOnMainThread: @selector(_getMTLConfigInfo:) withObject: retArray waitUntilDone: YES]; 117 } 118 NSNumber * num = (NSNumber *)[retArray objectAtIndex: 0]; 119 ret = (jlong)[num longValue]; 120 JNF_COCOA_EXIT(env); 121 return ret; 122 } 123 124 125 126 127 @implementation MTLGraphicsConfigUtil 128 + (void) _getMTLConfigInfo: (NSMutableArray *)argValue { 129 AWT_ASSERT_APPKIT_THREAD; 130 131 jint displayID = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue]; 132 NSString *mtlShadersLib = (NSString *)[argValue objectAtIndex: 1]; 133 JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; 134 [argValue removeAllObjects]; 135 136 J2dRlsTraceLn(J2D_TRACE_INFO, "MTLGraphicsConfig_getMTLConfigInfo"); 137 138 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 139 140 141 NSRect contentRect = NSMakeRect(0, 0, 64, 64); 142 NSWindow *window = 143 [[NSWindow alloc] 144 initWithContentRect: contentRect 145 styleMask: NSBorderlessWindowMask 146 backing: NSBackingStoreBuffered 147 defer: false]; 148 if (window == nil) { 149 J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: NSWindow is NULL"); 150 [argValue addObject: [NSNumber numberWithLong: 0L]]; 151 return; 152 } 153 154 NSView *scratchSurface = 155 [[NSView alloc] 156 initWithFrame: contentRect]; 157 if (scratchSurface == nil) { 158 J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: NSView is NULL"); 159 [argValue addObject: [NSNumber numberWithLong: 0L]]; 160 return; 161 } 162 [window setContentView: scratchSurface]; 163 164 MTLContext *mtlc = [[MTLContext alloc] initWithDevice:CGDirectDisplayCopyCurrentMetalDevice(displayID) 165 shadersLib:mtlShadersLib]; 166 if (mtlc == 0L) { 167 J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGC_InitMTLContext: could not allocate memory for mtlc"); 168 [argValue addObject: [NSNumber numberWithLong: 0L]]; 169 return; 170 } 171 172 173 // create the MTLGraphicsConfigInfo record for this config 174 MTLGraphicsConfigInfo *mtlinfo = (MTLGraphicsConfigInfo *)malloc(sizeof(MTLGraphicsConfigInfo)); 175 if (mtlinfo == NULL) { 176 J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLGraphicsConfig_getMTLConfigInfo: could not allocate memory for mtlinfo"); 177 free(mtlc); 178 [argValue addObject: [NSNumber numberWithLong: 0L]]; 179 return; 180 } 181 memset(mtlinfo, 0, sizeof(MTLGraphicsConfigInfo)); 182 mtlinfo->screen = displayID; 183 mtlinfo->context = mtlc; 184 185 [argValue addObject: [NSNumber numberWithLong:ptr_to_jlong(mtlinfo)]]; 186 [pool drain]; 187 } 188 @end //GraphicsConfigUtil 189 190 191 JNIEXPORT jint JNICALL 192 Java_sun_java2d_metal_MTLGraphicsConfig_nativeGetMaxTextureSize 193 (JNIEnv *env, jclass mtlgc) 194 { 195 J2dTraceLn(J2D_TRACE_INFO, "MTLGraphicsConfig_nativeGetMaxTextureSize"); 196 197 __block int max = 0; 198 199 // [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ 200 // }]; 201 202 return (jint)max; 203 }