--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#import "sun_java2d_opengl_CGLGraphicsConfig.h"
+
+#import "CGLGraphicsConfig.h"
+#import "CGLSurfaceData.h"
+#import "ThreadUtilities.h"
+
+#import <stdlib.h>
+#import <string.h>
+#import <ApplicationServices/ApplicationServices.h>
+#import <JavaNativeFoundation/JavaNativeFoundation.h>
+
+#pragma mark -
+#pragma mark "--- Mac OS X specific methods for GL pipeline ---"
+
+/**
+ * Disposes all memory and resources associated with the given
+ * CGLGraphicsConfigInfo (including its native OGLContext data).
+ */
+void
+OGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "OGLGC_DestroyOGLGraphicsConfig");
+
+ CGLGraphicsConfigInfo *cglinfo =
+ (CGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
+ if (cglinfo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR,
+ "OGLGC_DestroyOGLGraphicsConfig: info is null");
+ return;
+ }
+
+ OGLContext *oglc = (OGLContext*)cglinfo->context;
+ if (oglc != NULL) {
+ OGLContext_DestroyContextResources(oglc);
+
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
+ if (ctxinfo != NULL) {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ [NSOpenGLContext clearCurrentContext];
+ [ctxinfo->context clearDrawable];
+ [ctxinfo->context release];
+ if (ctxinfo->scratchSurface != 0) {
+ [ctxinfo->scratchSurface release];
+ }
+ [pool drain];
+ free(ctxinfo);
+ oglc->ctxInfo = NULL;
+ }
+ cglinfo->context = NULL;
+ }
+
+ free(cglinfo);
+}
+
+#pragma mark -
+#pragma mark "--- CGLGraphicsConfig methods ---"
+
+#ifdef REMOTELAYER
+mach_port_t JRSRemotePort;
+int remoteSocketFD = -1;
+
+static void *JRSRemoteThreadFn(void *data) {
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ // Negotiate a unix domain socket to communicate the
+ // out of band data: to read the mach port server name, and
+ // subsequently write out the layer ID.
+ static char* sock_path = "/tmp/JRSRemoteDemoSocket";
+ struct sockaddr_un address;
+ int socket_fd, nbytes;
+ int BUFLEN = 256;
+ char buffer[BUFLEN];
+
+ remoteSocketFD = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if (remoteSocketFD < 0) {
+ NSLog(@"socket() failed");
+ return NULL;
+ }
+ memset(&address, 0, sizeof(struct sockaddr_un));
+ address.sun_family = AF_UNIX;
+ memcpy(address.sun_path, sock_path, strlen(sock_path)+1);
+ int tries=0, status=-1;
+ while (status !=0 && tries<600) {
+ status = connect(remoteSocketFD, (struct sockaddr *) &address,
+ sizeof(struct sockaddr_un));
+ if (status != 0) {
+ tries++;
+ NSLog(@"connection attempt %d failed.", tries);
+ usleep(5000000);
+ }
+ }
+ if (status != 0) {
+ NSLog(@"failed to connect");
+ return NULL;
+ }
+ nbytes = read(remoteSocketFD, buffer, BUFLEN);
+ NSString* serverString = [[NSString alloc] initWithUTF8String:buffer];
+ CFRetain(serverString);
+ NSLog(@"Read server name %@", serverString);
+ JRSRemotePort = [JRSRenderServer recieveRenderServer:serverString];
+ NSLog(@"Read server port %d", JRSRemotePort);
+
+ [pool drain];
+ return NULL;
+}
+
+void sendLayerID(int layerID) {
+ if (JRSRemotePort == 0 || remoteSocketFD < 0) {
+ NSLog(@"No connection to send ID");
+ return;
+ }
+ int BUFLEN = 256;
+ char buffer[BUFLEN];
+ snprintf(buffer, BUFLEN, "%d", layerID);
+ write(remoteSocketFD, buffer, BUFLEN);
+}
+#endif /* REMOTELAYER */
+
+/**
+ * This is a globally shared context used when creating textures. When any
+ * new contexts are created, they specify this context as the "share list"
+ * context, which means any texture objects created when this shared context
+ * is current will be available to any other context in any other thread.
+ */
+NSOpenGLContext *sharedContext = NULL;
+NSOpenGLPixelFormat *sharedPixelFormat = NULL;
+
+/**
+ * Attempts to initialize CGL and the core OpenGL library.
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_java2d_opengl_CGLGraphicsConfig_initCGL
+ (JNIEnv *env, jclass cglgc)
+{
+ J2dRlsTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_initCGL");
+
+ if (!OGLFuncs_OpenLibrary()) {
+ return JNI_FALSE;
+ }
+
+ if (!OGLFuncs_InitPlatformFuncs() ||
+ !OGLFuncs_InitBaseFuncs() ||
+ !OGLFuncs_InitExtFuncs())
+ {
+ OGLFuncs_CloseLibrary();
+ return JNI_FALSE;
+ }
+#ifdef REMOTELAYER
+ pthread_t jrsRemoteThread;
+ pthread_create(&jrsRemoteThread, NULL, JRSRemoteThreadFn, NULL);
+#endif
+ return JNI_TRUE;
+}
+
+
+/**
+ * Determines whether the CGL pipeline can be used for a given GraphicsConfig
+ * provided its screen number and visual ID. If the minimum requirements are
+ * met, the native CGLGraphicsConfigInfo structure is initialized for this
+ * GraphicsConfig with the necessary information (pixel format, etc.)
+ * and a pointer to this structure is returned as a jlong. If
+ * initialization fails at any point, zero is returned, indicating that CGL
+ * cannot be used for this GraphicsConfig (we should fallback on an existing
+ * 2D pipeline).
+ */
+JNIEXPORT jlong JNICALL
+Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo
+ (JNIEnv *env, jclass cglgc,
+ jint displayID, jint pixfmt, jint swapInterval)
+{
+ jlong ret = 0L;
+ JNF_COCOA_ENTER(env);
+ NSMutableArray * retArray = [NSMutableArray arrayWithCapacity:3];
+ [retArray addObject: [NSNumber numberWithInt: (int)displayID]];
+ [retArray addObject: [NSNumber numberWithInt: (int)pixfmt]];
+ [retArray addObject: [NSNumber numberWithInt: (int)swapInterval]];
+ if ([NSThread isMainThread]) {
+ [GraphicsConfigUtil _getCGLConfigInfo: retArray];
+ } else {
+ [GraphicsConfigUtil performSelectorOnMainThread: @selector(_getCGLConfigInfo:) withObject: retArray waitUntilDone: YES];
+ }
+ NSNumber * num = (NSNumber *)[retArray objectAtIndex: 0];
+ ret = (jlong)[num longValue];
+ JNF_COCOA_EXIT(env);
+ return ret;
+}
+
+
+
+@implementation GraphicsConfigUtil
++ (void) _getCGLConfigInfo: (NSMutableArray *)argValue {
+ AWT_ASSERT_APPKIT_THREAD;
+
+ jint displayID = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue];
+ jint pixfmt = (jint)[(NSNumber *)[argValue objectAtIndex: 1] intValue];
+ jint swapInterval = (jint)[(NSNumber *)[argValue objectAtIndex: 2] intValue];
+ JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
+ [argValue removeAllObjects];
+
+ J2dRlsTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_getCGLConfigInfo");
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ CGOpenGLDisplayMask glMask = (CGOpenGLDisplayMask)pixfmt;
+ if (sharedContext == NULL) {
+ if (glMask == 0) {
+ glMask = CGDisplayIDToOpenGLDisplayMask(displayID);
+ }
+
+ NSOpenGLPixelFormatAttribute attrs[] = {
+ NSOpenGLPFAAllowOfflineRenderers,
+ NSOpenGLPFAClosestPolicy,
+ NSOpenGLPFAWindow,
+ NSOpenGLPFAPixelBuffer,
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAColorSize, 32,
+ NSOpenGLPFAAlphaSize, 8,
+ NSOpenGLPFADepthSize, 16,
+ NSOpenGLPFAScreenMask, glMask,
+ 0
+ };
+
+ sharedPixelFormat =
+ [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
+ if (sharedPixelFormat == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLPixelFormat is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+
+ sharedContext =
+ [[NSOpenGLContext alloc]
+ initWithFormat:sharedPixelFormat
+ shareContext: NULL];
+ if (sharedContext == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLContext is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ }
+
+#if USE_NSVIEW_FOR_SCRATCH
+ NSRect contentRect = NSMakeRect(0, 0, 64, 64);
+ NSWindow *window =
+ [[NSWindow alloc]
+ initWithContentRect: contentRect
+ styleMask: NSBorderlessWindowMask
+ backing: NSBackingStoreBuffered
+ defer: false];
+ if (window == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSWindow is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+
+ NSView *scratchSurface =
+ [[NSView alloc]
+ initWithFrame: contentRect];
+ if (scratchSurface == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSView is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ [window setContentView: scratchSurface];
+#else
+ NSOpenGLPixelBuffer *scratchSurface =
+ [[NSOpenGLPixelBuffer alloc]
+ initWithTextureTarget:GL_TEXTURE_2D
+ textureInternalFormat:GL_RGB
+ textureMaxMipMapLevel:0
+ pixelsWide:64
+ pixelsHigh:64];
+#endif
+
+ NSOpenGLContext *context =
+ [[NSOpenGLContext alloc]
+ initWithFormat: sharedPixelFormat
+ shareContext: sharedContext];
+ if (context == nil) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSOpenGLContext is NULL");
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+
+ GLint contextVirtualScreen = [context currentVirtualScreen];
+#if USE_NSVIEW_FOR_SCRATCH
+ [context setView: scratchSurface];
+#else
+ [context
+ setPixelBuffer: scratchSurface
+ cubeMapFace:0
+ mipMapLevel:0
+ currentVirtualScreen: contextVirtualScreen];
+#endif
+ [context makeCurrentContext];
+
+ // get version and extension strings
+ const unsigned char *versionstr = j2d_glGetString(GL_VERSION);
+ if (!OGLContext_IsVersionSupported(versionstr)) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: OpenGL 1.2 is required");
+ [NSOpenGLContext clearCurrentContext];
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ J2dRlsTraceLn1(J2D_TRACE_INFO, "CGLGraphicsConfig_getCGLConfigInfo: OpenGL version=%s", versionstr);
+
+ jint caps = CAPS_EMPTY;
+ OGLContext_GetExtensionInfo(env, &caps);
+
+ GLint value = 0;
+ [sharedPixelFormat
+ getValues: &value
+ forAttribute: NSOpenGLPFADoubleBuffer
+ forVirtualScreen: contextVirtualScreen];
+ if (value != 0) {
+ caps |= CAPS_DOUBLEBUFFERED;
+ }
+
+ J2dRlsTraceLn1(J2D_TRACE_INFO,
+ "CGLGraphicsConfig_getCGLConfigInfo: db=%d",
+ (caps & CAPS_DOUBLEBUFFERED) != 0);
+
+ // remove before shipping (?)
+#if 1
+ [sharedPixelFormat
+ getValues: &value
+ forAttribute: NSOpenGLPFAAccelerated
+ forVirtualScreen: contextVirtualScreen];
+ if (value == 0) {
+ [sharedPixelFormat
+ getValues: &value
+ forAttribute: NSOpenGLPFARendererID
+ forVirtualScreen: contextVirtualScreen];
+ fprintf(stderr, "WARNING: GL pipe is running in software mode (Renderer ID=0x%x)\n", (int)value);
+ }
+#endif
+
+ // 0: the buffers are swapped with no regard to the vertical refresh rate
+ // 1: the buffers are swapped only during the vertical retrace
+ GLint params = swapInterval;
+ [context setValues: ¶ms forParameter: NSOpenGLCPSwapInterval];
+
+ CGLCtxInfo *ctxinfo = (CGLCtxInfo *)malloc(sizeof(CGLCtxInfo));
+ if (ctxinfo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGC_InitOGLContext: could not allocate memory for ctxinfo");
+ [NSOpenGLContext clearCurrentContext];
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ memset(ctxinfo, 0, sizeof(CGLCtxInfo));
+ ctxinfo->context = context;
+ ctxinfo->scratchSurface = scratchSurface;
+
+ OGLContext *oglc = (OGLContext *)malloc(sizeof(OGLContext));
+ if (oglc == 0L) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGC_InitOGLContext: could not allocate memory for oglc");
+ [NSOpenGLContext clearCurrentContext];
+ free(ctxinfo);
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ memset(oglc, 0, sizeof(OGLContext));
+ oglc->ctxInfo = ctxinfo;
+ oglc->caps = caps;
+
+ // create the CGLGraphicsConfigInfo record for this config
+ CGLGraphicsConfigInfo *cglinfo = (CGLGraphicsConfigInfo *)malloc(sizeof(CGLGraphicsConfigInfo));
+ if (cglinfo == NULL) {
+ J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: could not allocate memory for cglinfo");
+ [NSOpenGLContext clearCurrentContext];
+ free(oglc);
+ free(ctxinfo);
+ [argValue addObject: [NSNumber numberWithLong: 0L]];
+ return;
+ }
+ memset(cglinfo, 0, sizeof(CGLGraphicsConfigInfo));
+ cglinfo->screen = displayID;
+ cglinfo->pixfmt = sharedPixelFormat;
+ cglinfo->context = oglc;
+
+ [NSOpenGLContext clearCurrentContext];
+ [argValue addObject: [NSNumber numberWithLong:ptr_to_jlong(cglinfo)]];
+ [pool drain];
+}
+@end //GraphicsConfigUtil
+
+JNIEXPORT jint JNICALL
+Java_sun_java2d_opengl_CGLGraphicsConfig_getOGLCapabilities
+ (JNIEnv *env, jclass cglgc, jlong configInfo)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_getOGLCapabilities");
+
+ CGLGraphicsConfigInfo *cglinfo =
+ (CGLGraphicsConfigInfo *)jlong_to_ptr(configInfo);
+ if ((cglinfo == NULL) || (cglinfo->context == NULL)) {
+ return CAPS_EMPTY;
+ } else {
+ return cglinfo->context->caps;
+ }
+}
+
+JNIEXPORT jint JNICALL
+Java_sun_java2d_opengl_CGLGraphicsConfig_nativeGetMaxTextureSize
+ (JNIEnv *env, jclass cglgc)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_nativeGetMaxTextureSize");
+
+ __block int max = 0;
+
+ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+ [sharedContext makeCurrentContext];
+ j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
+ [NSOpenGLContext clearCurrentContext];
+ }];
+
+ return (jint)max;
+}