Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/native_NOTIOS/sun/java2d/opengl/CGLGraphicsConfig.m
38829 views
/*1* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#import <stdlib.h>26#import <string.h>27#import <ApplicationServices/ApplicationServices.h>28#import <JavaNativeFoundation/JavaNativeFoundation.h>2930#import "sun_java2d_opengl_CGLGraphicsConfig.h"3132#import "jni.h"33#import "jni_util.h"34#import "CGLGraphicsConfig.h"35#import "CGLSurfaceData.h"36#import "LWCToolkit.h"37#import "ThreadUtilities.h"3839#pragma mark -40#pragma mark "--- Mac OS X specific methods for GL pipeline ---"4142/**43* Disposes all memory and resources associated with the given44* CGLGraphicsConfigInfo (including its native OGLContext data).45*/46void47OGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo)48{49J2dTraceLn(J2D_TRACE_INFO, "OGLGC_DestroyOGLGraphicsConfig");5051CGLGraphicsConfigInfo *cglinfo =52(CGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);53if (cglinfo == NULL) {54J2dRlsTraceLn(J2D_TRACE_ERROR,55"OGLGC_DestroyOGLGraphicsConfig: info is null");56return;57}5859OGLContext *oglc = (OGLContext*)cglinfo->context;60if (oglc != NULL) {61OGLContext_DestroyContextResources(oglc);6263CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;64if (ctxinfo != NULL) {65NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];66[NSOpenGLContext clearCurrentContext];67[ctxinfo->context clearDrawable];68[ctxinfo->context release];69if (ctxinfo->scratchSurface != 0) {70[ctxinfo->scratchSurface release];71}72[pool drain];73free(ctxinfo);74oglc->ctxInfo = NULL;75}76cglinfo->context = NULL;77}7879free(cglinfo);80}8182#pragma mark -83#pragma mark "--- CGLGraphicsConfig methods ---"8485#ifdef REMOTELAYER86mach_port_t JRSRemotePort;87int remoteSocketFD = -1;8889static void *JRSRemoteThreadFn(void *data) {90NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];9192// Negotiate a unix domain socket to communicate the93// out of band data: to read the mach port server name, and94// subsequently write out the layer ID.95static char* sock_path = "/tmp/JRSRemoteDemoSocket";96struct sockaddr_un address;97int socket_fd, nbytes;98int BUFLEN = 256;99char buffer[BUFLEN];100101remoteSocketFD = socket(PF_LOCAL, SOCK_STREAM, 0);102if (remoteSocketFD < 0) {103NSLog(@"socket() failed");104return NULL;105}106memset(&address, 0, sizeof(struct sockaddr_un));107address.sun_family = AF_UNIX;108memcpy(address.sun_path, sock_path, strlen(sock_path)+1);109int tries=0, status=-1;110while (status !=0 && tries<600) {111status = connect(remoteSocketFD, (struct sockaddr *) &address,112sizeof(struct sockaddr_un));113if (status != 0) {114tries++;115NSLog(@"connection attempt %d failed.", tries);116usleep(5000000);117}118}119if (status != 0) {120NSLog(@"failed to connect");121return NULL;122}123nbytes = read(remoteSocketFD, buffer, BUFLEN);124NSString* serverString = [[NSString alloc] initWithUTF8String:buffer];125CFRetain(serverString);126NSLog(@"Read server name %@", serverString);127JRSRemotePort = [JRSRenderServer recieveRenderServer:serverString];128NSLog(@"Read server port %d", JRSRemotePort);129130[pool drain];131return NULL;132}133134void sendLayerID(int layerID) {135if (JRSRemotePort == 0 || remoteSocketFD < 0) {136NSLog(@"No connection to send ID");137return;138}139int BUFLEN = 256;140char buffer[BUFLEN];141snprintf(buffer, BUFLEN, "%d", layerID);142write(remoteSocketFD, buffer, BUFLEN);143}144#endif /* REMOTELAYER */145146/**147* This is a globally shared context used when creating textures. When any148* new contexts are created, they specify this context as the "share list"149* context, which means any texture objects created when this shared context150* is current will be available to any other context in any other thread.151*/152NSOpenGLContext *sharedContext = NULL;153NSOpenGLPixelFormat *sharedPixelFormat = NULL;154155/**156* Attempts to initialize CGL and the core OpenGL library.157*/158JNIEXPORT jboolean JNICALL159Java_sun_java2d_opengl_CGLGraphicsConfig_initCGL160(JNIEnv *env, jclass cglgc)161{162J2dRlsTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_initCGL");163164if (!OGLFuncs_OpenLibrary()) {165return JNI_FALSE;166}167168if (!OGLFuncs_InitPlatformFuncs() ||169!OGLFuncs_InitBaseFuncs() ||170!OGLFuncs_InitExtFuncs())171{172OGLFuncs_CloseLibrary();173return JNI_FALSE;174}175#ifdef REMOTELAYER176pthread_t jrsRemoteThread;177pthread_create(&jrsRemoteThread, NULL, JRSRemoteThreadFn, NULL);178#endif179return JNI_TRUE;180}181182183/**184* Determines whether the CGL pipeline can be used for a given GraphicsConfig185* provided its screen number and visual ID. If the minimum requirements are186* met, the native CGLGraphicsConfigInfo structure is initialized for this187* GraphicsConfig with the necessary information (pixel format, etc.)188* and a pointer to this structure is returned as a jlong. If189* initialization fails at any point, zero is returned, indicating that CGL190* cannot be used for this GraphicsConfig (we should fallback on an existing191* 2D pipeline).192*/193JNIEXPORT jlong JNICALL194Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo195(JNIEnv *env, jclass cglgc,196jint displayID, jint pixfmt, jint swapInterval)197{198jlong ret = 0L;199JNF_COCOA_ENTER(env);200NSMutableArray * retArray = [NSMutableArray arrayWithCapacity:3];201[retArray addObject: [NSNumber numberWithInt: (int)displayID]];202[retArray addObject: [NSNumber numberWithInt: (int)pixfmt]];203[retArray addObject: [NSNumber numberWithInt: (int)swapInterval]];204if ([NSThread isMainThread]) {205[GraphicsConfigUtil _getCGLConfigInfo: retArray];206} else {207[GraphicsConfigUtil performSelectorOnMainThread: @selector(_getCGLConfigInfo:) withObject: retArray waitUntilDone: YES];208}209NSNumber * num = (NSNumber *)[retArray objectAtIndex: 0];210ret = (jlong)[num longValue];211JNF_COCOA_EXIT(env);212return ret;213}214215216217@implementation GraphicsConfigUtil218+ (void) _getCGLConfigInfo: (NSMutableArray *)argValue {219AWT_ASSERT_APPKIT_THREAD;220221jint displayID = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue];222jint swapInterval = (jint)[(NSNumber *)[argValue objectAtIndex: 2] intValue];223JNIEnv *env = [ThreadUtilities getJNIEnvUncached];224[argValue removeAllObjects];225226J2dRlsTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_getCGLConfigInfo");227228NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];229230if (sharedContext == NULL) {231232NSOpenGLPixelFormatAttribute attrs[] = {233NSOpenGLPFAAllowOfflineRenderers,234NSOpenGLPFAClosestPolicy,235NSOpenGLPFAWindow,236NSOpenGLPFAPixelBuffer,237NSOpenGLPFADoubleBuffer,238NSOpenGLPFAColorSize, 32,239NSOpenGLPFAAlphaSize, 8,240NSOpenGLPFADepthSize, 16,2410242};243244sharedPixelFormat =245[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];246if (sharedPixelFormat == nil) {247J2dRlsTraceLn(J2D_TRACE_ERROR,248"CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLPixelFormat is NULL");249250[argValue addObject: [NSNumber numberWithLong: 0L]];251return;252}253254sharedContext =255[[NSOpenGLContext alloc]256initWithFormat:sharedPixelFormat257shareContext: NULL];258if (sharedContext == nil) {259J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLContext is NULL");260[argValue addObject: [NSNumber numberWithLong: 0L]];261return;262}263}264265#if USE_NSVIEW_FOR_SCRATCH266NSRect contentRect = NSMakeRect(0, 0, 64, 64);267NSWindow *window =268[[NSWindow alloc]269initWithContentRect: contentRect270styleMask: NSBorderlessWindowMask271backing: NSBackingStoreBuffered272defer: false];273if (window == nil) {274J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSWindow is NULL");275[argValue addObject: [NSNumber numberWithLong: 0L]];276return;277}278279NSView *scratchSurface =280[[NSView alloc]281initWithFrame: contentRect];282if (scratchSurface == nil) {283J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSView is NULL");284[argValue addObject: [NSNumber numberWithLong: 0L]];285return;286}287[window setContentView: scratchSurface];288#else289NSOpenGLPixelBuffer *scratchSurface =290[[NSOpenGLPixelBuffer alloc]291initWithTextureTarget:GL_TEXTURE_2D292textureInternalFormat:GL_RGB293textureMaxMipMapLevel:0294pixelsWide:64295pixelsHigh:64];296#endif297298NSOpenGLContext *context =299[[NSOpenGLContext alloc]300initWithFormat: sharedPixelFormat301shareContext: sharedContext];302if (context == nil) {303J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSOpenGLContext is NULL");304[argValue addObject: [NSNumber numberWithLong: 0L]];305return;306}307308GLint contextVirtualScreen = [context currentVirtualScreen];309#if USE_NSVIEW_FOR_SCRATCH310[context setView: scratchSurface];311#else312[context313setPixelBuffer: scratchSurface314cubeMapFace:0315mipMapLevel:0316currentVirtualScreen: contextVirtualScreen];317#endif318[context makeCurrentContext];319320// get version and extension strings321const unsigned char *versionstr = j2d_glGetString(GL_VERSION);322if (!OGLContext_IsVersionSupported(versionstr)) {323J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: OpenGL 1.2 is required");324[NSOpenGLContext clearCurrentContext];325[argValue addObject: [NSNumber numberWithLong: 0L]];326return;327}328J2dRlsTraceLn1(J2D_TRACE_INFO, "CGLGraphicsConfig_getCGLConfigInfo: OpenGL version=%s", versionstr);329330jint caps = CAPS_EMPTY;331OGLContext_GetExtensionInfo(env, &caps);332333GLint value = 0;334[sharedPixelFormat335getValues: &value336forAttribute: NSOpenGLPFADoubleBuffer337forVirtualScreen: contextVirtualScreen];338if (value != 0) {339caps |= CAPS_DOUBLEBUFFERED;340}341[sharedPixelFormat342getValues: &value343forAttribute: NSOpenGLPFAAlphaSize344forVirtualScreen: contextVirtualScreen];345if (value != 0) {346caps |= CAPS_STORED_ALPHA;347}348349J2dRlsTraceLn2(J2D_TRACE_INFO,350"CGLGraphicsConfig_getCGLConfigInfo: db=%d alpha=%d",351(caps & CAPS_DOUBLEBUFFERED) != 0,352(caps & CAPS_STORED_ALPHA) != 0);353354// remove before shipping (?)355#if 1356[sharedPixelFormat357getValues: &value358forAttribute: NSOpenGLPFAAccelerated359forVirtualScreen: contextVirtualScreen];360if (value == 0) {361[sharedPixelFormat362getValues: &value363forAttribute: NSOpenGLPFARendererID364forVirtualScreen: contextVirtualScreen];365fprintf(stderr, "WARNING: GL pipe is running in software mode (Renderer ID=0x%x)\n", (int)value);366}367#endif368369// 0: the buffers are swapped with no regard to the vertical refresh rate370// 1: the buffers are swapped only during the vertical retrace371GLint params = swapInterval;372[context setValues: ¶ms forParameter: NSOpenGLCPSwapInterval];373374CGLCtxInfo *ctxinfo = (CGLCtxInfo *)malloc(sizeof(CGLCtxInfo));375if (ctxinfo == NULL) {376J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGC_InitOGLContext: could not allocate memory for ctxinfo");377[NSOpenGLContext clearCurrentContext];378[argValue addObject: [NSNumber numberWithLong: 0L]];379return;380}381memset(ctxinfo, 0, sizeof(CGLCtxInfo));382ctxinfo->context = context;383ctxinfo->scratchSurface = scratchSurface;384385OGLContext *oglc = (OGLContext *)malloc(sizeof(OGLContext));386if (oglc == 0L) {387J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGC_InitOGLContext: could not allocate memory for oglc");388[NSOpenGLContext clearCurrentContext];389free(ctxinfo);390[argValue addObject: [NSNumber numberWithLong: 0L]];391return;392}393memset(oglc, 0, sizeof(OGLContext));394oglc->ctxInfo = ctxinfo;395oglc->caps = caps;396397// create the CGLGraphicsConfigInfo record for this config398CGLGraphicsConfigInfo *cglinfo = (CGLGraphicsConfigInfo *)malloc(sizeof(CGLGraphicsConfigInfo));399if (cglinfo == NULL) {400J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: could not allocate memory for cglinfo");401[NSOpenGLContext clearCurrentContext];402free(oglc);403free(ctxinfo);404[argValue addObject: [NSNumber numberWithLong: 0L]];405return;406}407memset(cglinfo, 0, sizeof(CGLGraphicsConfigInfo));408cglinfo->screen = displayID;409cglinfo->pixfmt = sharedPixelFormat;410cglinfo->context = oglc;411412[NSOpenGLContext clearCurrentContext];413[argValue addObject: [NSNumber numberWithLong:ptr_to_jlong(cglinfo)]];414[pool drain];415}416@end //GraphicsConfigUtil417418JNIEXPORT jint JNICALL419Java_sun_java2d_opengl_CGLGraphicsConfig_getOGLCapabilities420(JNIEnv *env, jclass cglgc, jlong configInfo)421{422J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_getOGLCapabilities");423424CGLGraphicsConfigInfo *cglinfo =425(CGLGraphicsConfigInfo *)jlong_to_ptr(configInfo);426if ((cglinfo == NULL) || (cglinfo->context == NULL)) {427return CAPS_EMPTY;428} else {429return cglinfo->context->caps;430}431}432433JNIEXPORT jint JNICALL434Java_sun_java2d_opengl_CGLGraphicsConfig_nativeGetMaxTextureSize435(JNIEnv *env, jclass cglgc)436{437J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_nativeGetMaxTextureSize");438439__block int max = 0;440441[ThreadUtilities performOnMainThreadWaiting:YES block:^(){442[sharedContext makeCurrentContext];443j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);444[NSOpenGLContext clearCurrentContext];445}];446447return (jint)max;448}449450451