src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalGraphicsConfig.m
branchmetal-prototype-branch
changeset 57196 a95707a39ff5
equal deleted inserted replaced
57195:bb0bd0cff018 57196:a95707a39ff5
       
     1 /*
       
     2  * Copyright (c) 2019, 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_MetalGraphicsConfig.h"
       
    27 
       
    28 #import "MetalGraphicsConfig.h"
       
    29 //#import "CGLSurfaceData.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 Metal pipeline ---"
       
    39 
       
    40 /**
       
    41  * Disposes all memory and resources associated with the given
       
    42  * CGLGraphicsConfigInfo (including its native OGLContext data).
       
    43  */
       
    44 /*void
       
    45 OGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo)
       
    46 {
       
    47     J2dTraceLn(J2D_TRACE_INFO, "OGLGC_DestroyOGLGraphicsConfig");
       
    48 
       
    49     CGLGraphicsConfigInfo *cglinfo =
       
    50         (CGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
       
    51     if (cglinfo == NULL) {
       
    52         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
    53                       "OGLGC_DestroyOGLGraphicsConfig: info is null");
       
    54         return;
       
    55     }
       
    56 
       
    57     OGLContext *oglc = (OGLContext*)cglinfo->context;
       
    58     if (oglc != NULL) {
       
    59         OGLContext_DestroyContextResources(oglc);
       
    60 
       
    61         CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
       
    62         if (ctxinfo != NULL) {
       
    63             NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
       
    64             [NSOpenGLContext clearCurrentContext];
       
    65             [ctxinfo->context clearDrawable];
       
    66             [ctxinfo->context release];
       
    67             if (ctxinfo->scratchSurface != 0) {
       
    68                 [ctxinfo->scratchSurface release];
       
    69             }
       
    70             [pool drain];
       
    71             free(ctxinfo);
       
    72             oglc->ctxInfo = NULL;
       
    73         }
       
    74         cglinfo->context = NULL;
       
    75     }
       
    76 
       
    77     free(cglinfo);
       
    78 }*/
       
    79 
       
    80 #pragma mark -
       
    81 #pragma mark "--- MetalGraphicsConfig methods ---"
       
    82 
       
    83 /*#ifdef REMOTELAYER
       
    84 mach_port_t JRSRemotePort;
       
    85 int remoteSocketFD = -1;
       
    86 
       
    87 static void *JRSRemoteThreadFn(void *data) {
       
    88     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
       
    89 
       
    90     // Negotiate a unix domain socket to communicate the
       
    91     // out of band data: to read the mach port server name, and
       
    92     // subsequently write out the layer ID.
       
    93     static char* sock_path = "/tmp/JRSRemoteDemoSocket";
       
    94     struct sockaddr_un address;
       
    95     int  socket_fd, nbytes;
       
    96     int BUFLEN = 256;
       
    97     char buffer[BUFLEN];
       
    98 
       
    99     remoteSocketFD = socket(PF_LOCAL, SOCK_STREAM, 0);
       
   100     if (remoteSocketFD < 0) {
       
   101         NSLog(@"socket() failed");
       
   102         return NULL;
       
   103     }
       
   104     memset(&address, 0, sizeof(struct sockaddr_un));
       
   105     address.sun_family = AF_UNIX;
       
   106     memcpy(address.sun_path, sock_path, strlen(sock_path)+1);
       
   107     int tries=0, status=-1;
       
   108     while (status !=0 && tries<600) {
       
   109         status = connect(remoteSocketFD, (struct sockaddr *) &address,
       
   110                          sizeof(struct sockaddr_un));
       
   111         if (status != 0) {
       
   112             tries++;
       
   113             NSLog(@"connection attempt %d failed.", tries);
       
   114             usleep(5000000);
       
   115         }
       
   116     }
       
   117     if (status != 0) {
       
   118         NSLog(@"failed to connect");
       
   119         return NULL;
       
   120     }
       
   121     nbytes = read(remoteSocketFD, buffer, BUFLEN);
       
   122     NSString* serverString = [[NSString alloc] initWithUTF8String:buffer];
       
   123     CFRetain(serverString);
       
   124     NSLog(@"Read server name %@", serverString);
       
   125     JRSRemotePort = [JRSRenderServer recieveRenderServer:serverString];
       
   126     NSLog(@"Read server port %d", JRSRemotePort);
       
   127 
       
   128     [pool drain];
       
   129     return NULL;
       
   130 }
       
   131 
       
   132 void sendLayerID(int layerID) {
       
   133     if (JRSRemotePort == 0 || remoteSocketFD < 0) {
       
   134         NSLog(@"No connection to send ID");
       
   135         return;
       
   136     }
       
   137     int BUFLEN = 256;
       
   138     char buffer[BUFLEN];
       
   139     snprintf(buffer, BUFLEN, "%d", layerID);
       
   140     write(remoteSocketFD, buffer, BUFLEN);
       
   141 }
       
   142 #endif*/  /* REMOTELAYER */
       
   143 
       
   144 /**
       
   145  * This is a globally shared context used when creating textures.  When any
       
   146  * new contexts are created, they specify this context as the "share list"
       
   147  * context, which means any texture objects created when this shared context
       
   148  * is current will be available to any other context in any other thread.
       
   149  */
       
   150 //NSOpenGLContext *sharedContext = NULL;
       
   151 //NSOpenGLPixelFormat *sharedPixelFormat = NULL;
       
   152 
       
   153 /**
       
   154  * Attempts to initialize CGL and the core OpenGL library.
       
   155  */
       
   156 /*JNIEXPORT jboolean JNICALL
       
   157 Java_sun_java2d_opengl_CGLGraphicsConfig_initCGL
       
   158     (JNIEnv *env, jclass cglgc)
       
   159 {
       
   160     J2dRlsTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_initCGL");
       
   161 
       
   162     if (!OGLFuncs_OpenLibrary()) {
       
   163         return JNI_FALSE;
       
   164     }
       
   165 
       
   166     if (!OGLFuncs_InitPlatformFuncs() ||
       
   167         !OGLFuncs_InitBaseFuncs() ||
       
   168         !OGLFuncs_InitExtFuncs())
       
   169     {
       
   170         OGLFuncs_CloseLibrary();
       
   171         return JNI_FALSE;
       
   172     }
       
   173 #ifdef REMOTELAYER
       
   174     pthread_t jrsRemoteThread;
       
   175     pthread_create(&jrsRemoteThread, NULL, JRSRemoteThreadFn, NULL);
       
   176 #endif
       
   177     return JNI_TRUE;
       
   178 }*/
       
   179 
       
   180 
       
   181 /**
       
   182  * Determines whether the CGL pipeline can be used for a given GraphicsConfig
       
   183  * provided its screen number and visual ID.  If the minimum requirements are
       
   184  * met, the native CGLGraphicsConfigInfo structure is initialized for this
       
   185  * GraphicsConfig with the necessary information (pixel format, etc.)
       
   186  * and a pointer to this structure is returned as a jlong.  If
       
   187  * initialization fails at any point, zero is returned, indicating that CGL
       
   188  * cannot be used for this GraphicsConfig (we should fallback on an existing
       
   189  * 2D pipeline).
       
   190  */
       
   191 JNIEXPORT jlong JNICALL
       
   192 Java_sun_java2d_metal_MetalGraphicsConfig_getMetalConfigInfo
       
   193     (JNIEnv *env, jclass metalgc,
       
   194      jint displayID, jint pixfmt)
       
   195 {
       
   196     //fprintf(stdout, "Jay : MetalGraphicsConfig_getMetalConfigInfo\n");fflush(stdout);
       
   197   jlong ret = 0L;
       
   198   JNF_COCOA_ENTER(env);
       
   199   NSMutableArray * retArray = [NSMutableArray arrayWithCapacity:2];
       
   200   [retArray addObject: [NSNumber numberWithInt: (int)displayID]];
       
   201   [retArray addObject: [NSNumber numberWithInt: (int)pixfmt]];
       
   202   //if ([NSThread isMainThread]) {
       
   203       //[GraphicsConfigUtil _getCGLConfigInfo: retArray];
       
   204   //} else {
       
   205       [MetalGraphicsConfigUtil performSelectorOnMainThread: @selector(_getMetalConfigInfo:) withObject: retArray waitUntilDone: YES];
       
   206   //}
       
   207   NSNumber * num = (NSNumber *)[retArray objectAtIndex: 0];
       
   208   ret = (jlong)[num longValue];
       
   209   JNF_COCOA_EXIT(env);
       
   210   return ret;
       
   211 }
       
   212 
       
   213 @implementation MetalGraphicsConfigUtil
       
   214 + (void) _getMetalConfigInfo: (NSMutableArray *)argValue {
       
   215     AWT_ASSERT_APPKIT_THREAD;
       
   216 
       
   217     //fprintf(stdout, "Jay : MetalGraphicsConfig_MetalGraphicsConfigUtil\n");fflush(stdout);
       
   218     jint displayID = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue];
       
   219     jint pixfmt = (jint)[(NSNumber *)[argValue objectAtIndex: 1] intValue];
       
   220     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
       
   221     [argValue removeAllObjects];
       
   222 
       
   223     //J2dRlsTraceLn(J2D_TRACE_INFO, "MetalGraphicsConfig_getMetalConfigInfo");
       
   224 
       
   225     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
       
   226 
       
   227     /*CGOpenGLDisplayMask glMask = (CGOpenGLDisplayMask)pixfmt;
       
   228     if (sharedContext == NULL) {
       
   229         if (glMask == 0) {
       
   230             glMask = CGDisplayIDToOpenGLDisplayMask(displayID);
       
   231         }
       
   232 
       
   233         NSOpenGLPixelFormatAttribute attrs[] = {
       
   234             NSOpenGLPFAAllowOfflineRenderers,
       
   235             NSOpenGLPFAClosestPolicy,
       
   236             NSOpenGLPFAWindow,
       
   237             NSOpenGLPFAPixelBuffer,
       
   238             NSOpenGLPFADoubleBuffer,
       
   239             NSOpenGLPFAColorSize, 32,
       
   240             NSOpenGLPFAAlphaSize, 8,
       
   241             NSOpenGLPFADepthSize, 16,
       
   242             NSOpenGLPFAScreenMask, glMask,
       
   243             0
       
   244         };
       
   245 
       
   246         sharedPixelFormat =
       
   247             [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
       
   248         if (sharedPixelFormat == nil) {
       
   249             J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLPixelFormat is NULL");
       
   250             [argValue addObject: [NSNumber numberWithLong: 0L]];
       
   251             return;
       
   252         }
       
   253 
       
   254         sharedContext =
       
   255             [[NSOpenGLContext alloc]
       
   256                 initWithFormat:sharedPixelFormat
       
   257                 shareContext: NULL];
       
   258         if (sharedContext == nil) {
       
   259             J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLContext is NULL");
       
   260             [argValue addObject: [NSNumber numberWithLong: 0L]];
       
   261             return;
       
   262         }
       
   263     }*/
       
   264     id<MTLDevice> device = MTLCreateSystemDefaultDevice();
       
   265     
       
   266     id<MTLCommandQueue> commandQueue = [device newCommandQueue];
       
   267     
       
   268     // Jay : Looks like no need to create MetaLayer here and we were creating
       
   269     // scratch surface only to make OGL context current. So no need to create any layer for
       
   270     // Metal. Just create device and commandQueue for Metal.
       
   271     //defaultLibrary = [device newDefaultLibrary];
       
   272     /*CAMetalLayer *metalLayer = [CAMetalLayer layer];
       
   273     metalLayer.device = device;
       
   274     metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;*/
       
   275     
       
   276 #if USE_NSVIEW_FOR_SCRATCH
       
   277     /*NSRect contentRect = NSMakeRect(0, 0, 64, 64);
       
   278     NSWindow *window =
       
   279         [[NSWindow alloc]
       
   280             initWithContentRect: contentRect
       
   281             styleMask: NSBorderlessWindowMask
       
   282             backing: NSBackingStoreBuffered
       
   283             defer: false];
       
   284     if (window == nil) {
       
   285         J2dRlsTraceLn(J2D_TRACE_ERROR, "MetalGraphicsConfig_getMetalConfigInfo: NSWindow is NULL");
       
   286         [argValue addObject: [NSNumber numberWithLong: 0L]];
       
   287         return;
       
   288     }
       
   289 
       
   290     NSView *scratchSurface =
       
   291         [[NSView alloc]
       
   292             initWithFrame: contentRect];
       
   293     if (scratchSurface == nil) {
       
   294         J2dRlsTraceLn(J2D_TRACE_ERROR, "MetalGraphicsConfig_getMetalConfigInfo: NSView is NULL");
       
   295         [argValue addObject: [NSNumber numberWithLong: 0L]];
       
   296         return;
       
   297     }
       
   298     [window setContentView: scratchSurface];*/
       
   299 #else
       
   300     /*NSOpenGLPixelBuffer *scratchSurface =
       
   301         [[NSOpenGLPixelBuffer alloc]
       
   302             initWithTextureTarget:GL_TEXTURE_2D
       
   303             textureInternalFormat:GL_RGB
       
   304             textureMaxMipMapLevel:0
       
   305             pixelsWide:64
       
   306             pixelsHigh:64];*/
       
   307 #endif
       
   308 
       
   309     /*NSOpenGLContext *context =
       
   310         [[NSOpenGLContext alloc]
       
   311             initWithFormat: sharedPixelFormat
       
   312             shareContext: sharedContext];
       
   313     if (context == nil) {
       
   314         J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSOpenGLContext is NULL");
       
   315         [argValue addObject: [NSNumber numberWithLong: 0L]];
       
   316         return;
       
   317     }
       
   318 
       
   319     GLint contextVirtualScreen = [context currentVirtualScreen];*/
       
   320 #if USE_NSVIEW_FOR_SCRATCH
       
   321     //[context setView: scratchSurface];
       
   322     // Jay : no need of scratch layer for metal
       
   323     //metalLayer.frame = scratchSurface.layer.frame;
       
   324     //[scratchSurface.layer addSublayer: metalLayer];
       
   325 #else
       
   326     /*[context
       
   327         setPixelBuffer: scratchSurface
       
   328         cubeMapFace:0
       
   329         mipMapLevel:0
       
   330         currentVirtualScreen: contextVirtualScreen];*/
       
   331 #endif
       
   332     /*[context makeCurrentContext];
       
   333 
       
   334     // get version and extension strings
       
   335     const unsigned char *versionstr = j2d_glGetString(GL_VERSION);
       
   336     if (!OGLContext_IsVersionSupported(versionstr)) {
       
   337         J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: OpenGL 1.2 is required");
       
   338         [NSOpenGLContext clearCurrentContext];
       
   339         [argValue addObject: [NSNumber numberWithLong: 0L]];
       
   340         return;
       
   341     }
       
   342     J2dRlsTraceLn1(J2D_TRACE_INFO, "CGLGraphicsConfig_getCGLConfigInfo: OpenGL version=%s", versionstr);
       
   343 
       
   344     jint caps = CAPS_EMPTY;
       
   345     OGLContext_GetExtensionInfo(env, &caps);
       
   346 
       
   347     GLint value = 0;
       
   348     [sharedPixelFormat
       
   349         getValues: &value
       
   350         forAttribute: NSOpenGLPFADoubleBuffer
       
   351         forVirtualScreen: contextVirtualScreen];
       
   352     if (value != 0) {
       
   353         caps |= CAPS_DOUBLEBUFFERED;
       
   354     }
       
   355 
       
   356     J2dRlsTraceLn1(J2D_TRACE_INFO,
       
   357                    "CGLGraphicsConfig_getCGLConfigInfo: db=%d",
       
   358                    (caps & CAPS_DOUBLEBUFFERED) != 0);*/
       
   359 
       
   360     // remove before shipping (?)
       
   361 #if 1
       
   362     /*[sharedPixelFormat
       
   363         getValues: &value
       
   364         forAttribute: NSOpenGLPFAAccelerated
       
   365         forVirtualScreen: contextVirtualScreen];
       
   366     if (value == 0) {
       
   367         [sharedPixelFormat
       
   368             getValues: &value
       
   369             forAttribute: NSOpenGLPFARendererID
       
   370             forVirtualScreen: contextVirtualScreen];
       
   371         fprintf(stderr, "WARNING: GL pipe is running in software mode (Renderer ID=0x%x)\n", (int)value);
       
   372     }*/
       
   373 #endif
       
   374 
       
   375     // 0: the buffers are swapped with no regard to the vertical refresh rate
       
   376     // 1: the buffers are swapped only during the vertical retrace
       
   377     /*GLint params = swapInterval;
       
   378     [context setValues: &params forParameter: NSOpenGLCPSwapInterval];
       
   379 
       
   380     CGLCtxInfo *ctxinfo = (CGLCtxInfo *)malloc(sizeof(CGLCtxInfo));
       
   381     if (ctxinfo == NULL) {
       
   382         J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGC_InitOGLContext: could not allocate memory for ctxinfo");
       
   383         [NSOpenGLContext clearCurrentContext];
       
   384         [argValue addObject: [NSNumber numberWithLong: 0L]];
       
   385         return;
       
   386     }
       
   387     memset(ctxinfo, 0, sizeof(CGLCtxInfo));
       
   388     ctxinfo->context = context;
       
   389     ctxinfo->scratchSurface = scratchSurface;
       
   390 
       
   391     OGLContext *oglc = (OGLContext *)malloc(sizeof(OGLContext));
       
   392     if (oglc == 0L) {
       
   393         J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGC_InitOGLContext: could not allocate memory for oglc");
       
   394         [NSOpenGLContext clearCurrentContext];
       
   395         free(ctxinfo);
       
   396         [argValue addObject: [NSNumber numberWithLong: 0L]];
       
   397         return;
       
   398     }
       
   399     memset(oglc, 0, sizeof(OGLContext));
       
   400     oglc->ctxInfo = ctxinfo;
       
   401     oglc->caps = caps;*/
       
   402 
       
   403     // create the CGLGraphicsConfigInfo record for this config
       
   404     MetalGraphicsConfigInfo *metalinfo = (MetalGraphicsConfigInfo *)malloc(sizeof(MetalGraphicsConfigInfo));
       
   405     if (metalinfo == NULL) {
       
   406         //J2dRlsTraceLn(J2D_TRACE_ERROR, "MetalGraphicsConfig_getMetalConfigInfo: could not allocate memory for cglinfo");
       
   407         //[NSOpenGLContext clearCurrentContext];
       
   408         //free(oglc);
       
   409         //free(ctxinfo);
       
   410         //[argValue addObject: [NSNumber numberWithLong: 0L]];
       
   411         return;
       
   412     }
       
   413     memset(metalinfo, 0, sizeof(MetalGraphicsConfigInfo));
       
   414     metalinfo->screen = displayID;
       
   415     metalinfo->device = device;
       
   416     metalinfo->commandQueue = commandQueue;
       
   417 
       
   418     //[NSOpenGLContext clearCurrentContext];
       
   419     [argValue addObject: [NSNumber numberWithLong:ptr_to_jlong(metalinfo)]];
       
   420     [pool drain];
       
   421 }
       
   422 @end //GraphicsConfigUtil
       
   423 
       
   424 /*JNIEXPORT jint JNICALL
       
   425 Java_sun_java2d_opengl_CGLGraphicsConfig_getOGLCapabilities
       
   426     (JNIEnv *env, jclass cglgc, jlong configInfo)
       
   427 {
       
   428     J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_getOGLCapabilities");
       
   429 
       
   430     CGLGraphicsConfigInfo *cglinfo =
       
   431         (CGLGraphicsConfigInfo *)jlong_to_ptr(configInfo);
       
   432     if ((cglinfo == NULL) || (cglinfo->context == NULL)) {
       
   433         return CAPS_EMPTY;
       
   434     } else {
       
   435         return cglinfo->context->caps;
       
   436     }
       
   437 }
       
   438 
       
   439 JNIEXPORT jint JNICALL
       
   440 Java_sun_java2d_opengl_CGLGraphicsConfig_nativeGetMaxTextureSize
       
   441     (JNIEnv *env, jclass cglgc)
       
   442 {
       
   443     J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_nativeGetMaxTextureSize");
       
   444 
       
   445     __block int max = 0;
       
   446 
       
   447     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
       
   448         [sharedContext makeCurrentContext];
       
   449         j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
       
   450         [NSOpenGLContext clearCurrentContext];
       
   451     }];
       
   452 
       
   453     return (jint)max;
       
   454 }*/