Path: blob/master/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m
41159 views
/*1* Copyright (c) 2011, 2020, 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 "sun_java2d_opengl_CGLGraphicsConfig.h"2627#import "CGLGraphicsConfig.h"28#import "CGLSurfaceData.h"29#import "ThreadUtilities.h"30#import "JNIUtilities.h"3132#import <stdlib.h>33#import <string.h>34#import <ApplicationServices/ApplicationServices.h>3536/**37* Disposes all memory and resources associated with the given38* CGLGraphicsConfigInfo (including its native OGLContext data).39*/40void41OGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo)42{43J2dTraceLn(J2D_TRACE_INFO, "OGLGC_DestroyOGLGraphicsConfig");4445CGLGraphicsConfigInfo *cglinfo =46(CGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);47if (cglinfo == NULL) {48J2dRlsTraceLn(J2D_TRACE_ERROR,49"OGLGC_DestroyOGLGraphicsConfig: info is null");50return;51}5253OGLContext *oglc = (OGLContext*)cglinfo->context;54if (oglc != NULL) {55OGLContext_DestroyContextResources(oglc);5657CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;58if (ctxinfo != NULL) {59NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];60[NSOpenGLContext clearCurrentContext];61[ctxinfo->context clearDrawable];62[ctxinfo->context release];63if (ctxinfo->scratchSurface != 0) {64[ctxinfo->scratchSurface release];65}66[pool drain];67free(ctxinfo);68oglc->ctxInfo = NULL;69}70cglinfo->context = NULL;71}7273free(cglinfo);74}7576/**77* This is a globally shared context used when creating textures. When any78* new contexts are created, they specify this context as the "share list"79* context, which means any texture objects created when this shared context80* is current will be available to any other context in any other thread.81*/82NSOpenGLContext *sharedContext = NULL;83NSOpenGLPixelFormat *sharedPixelFormat = NULL;8485/**86* Attempts to initialize CGL and the core OpenGL library.87*/88JNIEXPORT jboolean JNICALL89Java_sun_java2d_opengl_CGLGraphicsConfig_initCGL90(JNIEnv *env, jclass cglgc)91{92J2dRlsTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_initCGL");9394if (!OGLFuncs_OpenLibrary()) {95return JNI_FALSE;96}9798if (!OGLFuncs_InitPlatformFuncs() ||99!OGLFuncs_InitBaseFuncs() ||100!OGLFuncs_InitExtFuncs())101{102OGLFuncs_CloseLibrary();103return JNI_FALSE;104}105return JNI_TRUE;106}107108/**109* Determines whether the CGL pipeline can be used for a given GraphicsConfig.110* If the minimum requirements are met, the native CGLGraphicsConfigInfo111* structure is initialized for this GraphicsConfig with the necessary112* information and a pointer to this structure is returned as a jlong. If113* initialization fails at any point, zero is returned, indicating that CGL114* cannot be used for this GraphicsConfig (we should fallback on an existing 2D115* pipeline).116*/117JNIEXPORT jlong JNICALL118Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo119(JNIEnv *env, jclass cglgc)120{121__block jlong ret = 0L;122JNI_COCOA_ENTER(env);123[ThreadUtilities performOnMainThreadWaiting:YES block:^(){124125JNIEnv *env = [ThreadUtilities getJNIEnvUncached];126127J2dRlsTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_getCGLConfigInfo");128129NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];130131if (sharedContext == NULL) {132133NSOpenGLPixelFormatAttribute attrs[] = {134NSOpenGLPFAAllowOfflineRenderers,135NSOpenGLPFAClosestPolicy,136NSOpenGLPFAWindow,137NSOpenGLPFAPixelBuffer,138NSOpenGLPFADoubleBuffer,139NSOpenGLPFAColorSize, 32,140NSOpenGLPFAAlphaSize, 8,141NSOpenGLPFADepthSize, 16,1420143};144145sharedPixelFormat =146[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];147if (sharedPixelFormat == nil) {148J2dRlsTraceLn(J2D_TRACE_ERROR,149"CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLPixelFormat is NULL");150return;151}152153sharedContext =154[[NSOpenGLContext alloc]155initWithFormat:sharedPixelFormat156shareContext: NULL];157if (sharedContext == nil) {158J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: shared NSOpenGLContext is NULL");159return;160}161}162163#if USE_NSVIEW_FOR_SCRATCH164NSRect contentRect = NSMakeRect(0, 0, 64, 64);165NSWindow *window =166[[NSWindow alloc]167initWithContentRect: contentRect168styleMask: NSBorderlessWindowMask169backing: NSBackingStoreBuffered170defer: false];171if (window == nil) {172J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSWindow is NULL");173return;174}175176NSView *scratchSurface =177[[NSView alloc]178initWithFrame: contentRect];179if (scratchSurface == nil) {180J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSView is NULL");181return;182}183[window setContentView: scratchSurface];184#else185NSOpenGLPixelBuffer *scratchSurface =186[[NSOpenGLPixelBuffer alloc]187initWithTextureTarget:GL_TEXTURE_2D188textureInternalFormat:GL_RGB189textureMaxMipMapLevel:0190pixelsWide:64191pixelsHigh:64];192#endif193194NSOpenGLContext *context =195[[NSOpenGLContext alloc]196initWithFormat: sharedPixelFormat197shareContext: sharedContext];198if (context == nil) {199J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: NSOpenGLContext is NULL");200return;201}202203GLint contextVirtualScreen = [context currentVirtualScreen];204#if USE_NSVIEW_FOR_SCRATCH205[context setView: scratchSurface];206#else207[context208setPixelBuffer: scratchSurface209cubeMapFace:0210mipMapLevel:0211currentVirtualScreen: contextVirtualScreen];212#endif213[context makeCurrentContext];214215// get version and extension strings216const unsigned char *versionstr = j2d_glGetString(GL_VERSION);217if (!OGLContext_IsVersionSupported(versionstr)) {218J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: OpenGL 1.2 is required");219[NSOpenGLContext clearCurrentContext];220return;221}222J2dRlsTraceLn1(J2D_TRACE_INFO, "CGLGraphicsConfig_getCGLConfigInfo: OpenGL version=%s", versionstr);223224jint caps = CAPS_EMPTY;225OGLContext_GetExtensionInfo(env, &caps);226227GLint value = 0;228[sharedPixelFormat229getValues: &value230forAttribute: NSOpenGLPFADoubleBuffer231forVirtualScreen: contextVirtualScreen];232if (value != 0) {233caps |= CAPS_DOUBLEBUFFERED;234}235236J2dRlsTraceLn1(J2D_TRACE_INFO,237"CGLGraphicsConfig_getCGLConfigInfo: db=%d",238(caps & CAPS_DOUBLEBUFFERED) != 0);239240// remove before shipping (?)241#if 1242[sharedPixelFormat243getValues: &value244forAttribute: NSOpenGLPFAAccelerated245forVirtualScreen: contextVirtualScreen];246if (value == 0) {247[sharedPixelFormat248getValues: &value249forAttribute: NSOpenGLPFARendererID250forVirtualScreen: contextVirtualScreen];251fprintf(stderr, "WARNING: GL pipe is running in software mode (Renderer ID=0x%x)\n", (int)value);252}253#endif254CGLCtxInfo *ctxinfo = (CGLCtxInfo *)malloc(sizeof(CGLCtxInfo));255if (ctxinfo == NULL) {256J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGC_InitOGLContext: could not allocate memory for ctxinfo");257[NSOpenGLContext clearCurrentContext];258return;259}260memset(ctxinfo, 0, sizeof(CGLCtxInfo));261ctxinfo->context = context;262ctxinfo->scratchSurface = scratchSurface;263264OGLContext *oglc = (OGLContext *)malloc(sizeof(OGLContext));265if (oglc == 0L) {266J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGC_InitOGLContext: could not allocate memory for oglc");267[NSOpenGLContext clearCurrentContext];268free(ctxinfo);269return;270}271memset(oglc, 0, sizeof(OGLContext));272oglc->ctxInfo = ctxinfo;273oglc->caps = caps;274275// create the CGLGraphicsConfigInfo record for this config276CGLGraphicsConfigInfo *cglinfo = (CGLGraphicsConfigInfo *)malloc(sizeof(CGLGraphicsConfigInfo));277if (cglinfo == NULL) {278J2dRlsTraceLn(J2D_TRACE_ERROR, "CGLGraphicsConfig_getCGLConfigInfo: could not allocate memory for cglinfo");279[NSOpenGLContext clearCurrentContext];280free(oglc);281free(ctxinfo);282return;283}284memset(cglinfo, 0, sizeof(CGLGraphicsConfigInfo));285cglinfo->context = oglc;286287[NSOpenGLContext clearCurrentContext];288ret = ptr_to_jlong(cglinfo);289[pool drain];290291}];292JNI_COCOA_EXIT(env);293return ret;294}295296JNIEXPORT jint JNICALL297Java_sun_java2d_opengl_CGLGraphicsConfig_getOGLCapabilities298(JNIEnv *env, jclass cglgc, jlong configInfo)299{300J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_getOGLCapabilities");301302CGLGraphicsConfigInfo *cglinfo =303(CGLGraphicsConfigInfo *)jlong_to_ptr(configInfo);304if ((cglinfo == NULL) || (cglinfo->context == NULL)) {305return CAPS_EMPTY;306} else {307return cglinfo->context->caps;308}309}310311JNIEXPORT jint JNICALL312Java_sun_java2d_opengl_CGLGraphicsConfig_nativeGetMaxTextureSize313(JNIEnv *env, jclass cglgc)314{315J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_nativeGetMaxTextureSize");316317__block int max = 0;318319[ThreadUtilities performOnMainThreadWaiting:YES block:^(){320[sharedContext makeCurrentContext];321j2d_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);322[NSOpenGLContext clearCurrentContext];323}];324325return (jint)max;326}327328329