--- old/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalSurfaceData.m 2019-06-14 14:39:07.000000000 +0530 +++ /dev/null 2019-06-14 14:39:07.000000000 +0530 @@ -1,532 +0,0 @@ -/* - * Copyright (c) 2019, 2019, 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 - -#import "sun_java2d_metal_MetalSurfaceData.h" - -#import "jni_util.h" -#import "MetalRenderQueue.h" -#import "MetalGraphicsConfig.h" -#import "MetalSurfaceData.h" -#import "ThreadUtilities.h" - -/* JDK's glext.h is already included and will prevent the Apple glext.h - * being included, so define the externs directly - */ -/*extern void glBindFramebufferEXT(GLenum target, GLuint framebuffer); -extern CGLError CGLTexImageIOSurface2D( - CGLContextObj ctx, GLenum target, GLenum internal_format, - GLsizei width, GLsizei height, GLenum format, GLenum type, - IOSurfaceRef ioSurface, GLuint plane);*/ - -/** - * The methods in this file implement the native windowing system specific - * layer (CGL) for the OpenGL-based Java 2D pipeline. - */ - -#pragma mark - -#pragma mark "--- Mac OS X specific methods for GL pipeline ---" - -// TODO: hack that's called from OGLRenderQueue to test out unlockFocus behavior -/*#if 0 -void -OGLSD_UnlockFocus(OGLContext *oglc, OGLSDOps *dstOps) -{ - CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo; - CGLSDOps *cglsdo = (CGLSDOps *)dstOps->privOps; - fprintf(stderr, "about to unlock focus: %p %p\n", - cglsdo->peerData, ctxinfo->context); - - NSOpenGLView *nsView = cglsdo->peerData; - if (nsView != NULL) { -JNF_COCOA_ENTER(env); - [nsView unlockFocus]; -JNF_COCOA_EXIT(env); - } -} -#endif*/ - -/** - * Makes the given context current to its associated "scratch" surface. If - * the operation is successful, this method will return JNI_TRUE; otherwise, - * returns JNI_FALSE. - */ -/*static jboolean -CGLSD_MakeCurrentToScratch(JNIEnv *env, OGLContext *oglc) -{ - J2dTraceLn(J2D_TRACE_INFO, "CGLSD_MakeCurrentToScratch"); - - if (oglc == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, - "CGLSD_MakeCurrentToScratch: context is null"); - return JNI_FALSE; - } - -JNF_COCOA_ENTER(env); - - CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo; -#if USE_NSVIEW_FOR_SCRATCH - [ctxinfo->context makeCurrentContext]; - [ctxinfo->context setView: ctxinfo->scratchSurface]; -#else - [ctxinfo->context clearDrawable]; - [ctxinfo->context makeCurrentContext]; - [ctxinfo->context setPixelBuffer: ctxinfo->scratchSurface - cubeMapFace: 0 - mipMapLevel: 0 - currentVirtualScreen: [ctxinfo->context currentVirtualScreen]]; -#endif - -JNF_COCOA_EXIT(env); - - return JNI_TRUE; -}*/ - -/** - * This function disposes of any native windowing system resources associated - * with this surface. - */ -/*void -OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo) -{ - J2dTraceLn(J2D_TRACE_INFO, "OGLSD_DestroyOGLSurface"); - -JNF_COCOA_ENTER(env); - - CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps; - if (oglsdo->drawableType == OGLSD_WINDOW) { - // detach the NSView from the NSOpenGLContext - CGLGraphicsConfigInfo *cglInfo = cglsdo->configInfo; - OGLContext *oglc = cglInfo->context; - CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo; - [ctxinfo->context clearDrawable]; - } - - oglsdo->drawableType = OGLSD_UNDEFINED; - -JNF_COCOA_EXIT(env); -}*/ - -/** - * Returns a pointer (as a jlong) to the native CGLGraphicsConfigInfo - * associated with the given OGLSDOps. This method can be called from - * shared code to retrieve the native GraphicsConfig data in a platform- - * independent manner. - */ -/*jlong -OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo) -{ - J2dTraceLn(J2D_TRACE_INFO, "OGLSD_GetNativeConfigInfo"); - - if (oglsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: ops are null"); - return 0L; - } - - CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps; - if (cglsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: cgl ops are null"); - return 0L; - } - - return ptr_to_jlong(cglsdo->configInfo); -}*/ - -/** - * Makes the given GraphicsConfig's context current to its associated - * "scratch" surface. If there is a problem making the context current, - * this method will return NULL; otherwise, returns a pointer to the - * OGLContext that is associated with the given GraphicsConfig. - */ -/*OGLContext * -OGLSD_SetScratchSurface(JNIEnv *env, jlong pConfigInfo) -{ - J2dTraceLn(J2D_TRACE_INFO, "OGLSD_SetScratchContext"); - - CGLGraphicsConfigInfo *cglInfo = (CGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo); - if (cglInfo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: cgl config info is null"); - return NULL; - } - - OGLContext *oglc = cglInfo->context; - if (oglc == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: ogl context is null"); - return NULL; - } - - CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo; - -JNF_COCOA_ENTER(env); - - // avoid changing the context's target view whenever possible, since - // calling setView causes flickering; as long as our context is current - // to some view, it's not necessary to switch to the scratch surface - if ([ctxinfo->context view] == nil) { - // it seems to be necessary to explicitly flush between context changes - OGLContext *currentContext = OGLRenderQueue_GetCurrentContext(); - if (currentContext != NULL) { - j2d_glFlush(); - } - - if (!CGLSD_MakeCurrentToScratch(env, oglc)) { - return NULL; - } - // make sure our context is current - } else if ([NSOpenGLContext currentContext] != ctxinfo->context) { - [ctxinfo->context makeCurrentContext]; - } - - if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) { - // the GL_EXT_framebuffer_object extension is present, so this call - // will ensure that we are bound to the scratch surface (and not - // some other framebuffer object) - j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - } - -JNF_COCOA_EXIT(env); - - return oglc; -}*/ - -/** - * Makes a context current to the given source and destination - * surfaces. If there is a problem making the context current, this method - * will return NULL; otherwise, returns a pointer to the OGLContext that is - * associated with the destination surface. - */ -/*OGLContext * -OGLSD_MakeOGLContextCurrent(JNIEnv *env, OGLSDOps *srcOps, OGLSDOps *dstOps) -{ - J2dTraceLn(J2D_TRACE_INFO, "OGLSD_MakeOGLContextCurrent"); - - CGLSDOps *dstCGLOps = (CGLSDOps *)dstOps->privOps; - - J2dTraceLn4(J2D_TRACE_VERBOSE, " src: %d %p dst: %d %p", srcOps->drawableType, srcOps, dstOps->drawableType, dstOps); - - OGLContext *oglc = dstCGLOps->configInfo->context; - if (oglc == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_MakeOGLContextCurrent: context is null"); - return NULL; - } - - CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo; - - // it seems to be necessary to explicitly flush between context changes - OGLContext *currentContext = OGLRenderQueue_GetCurrentContext(); - if (currentContext != NULL) { - j2d_glFlush(); - } - - if (dstOps->drawableType == OGLSD_FBOBJECT) { - // first make sure we have a current context (if the context isn't - // already current to some drawable, we will make it current to - // its scratch surface) - if (oglc != currentContext) { - if (!CGLSD_MakeCurrentToScratch(env, oglc)) { - return NULL; - } - } - - // now bind to the fbobject associated with the destination surface; - // this means that all rendering will go into the fbobject destination - // (note that we unbind the currently bound texture first; this is - // recommended procedure when binding an fbobject) - j2d_glBindTexture(GL_TEXTURE_2D, 0); - j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, dstOps->fbobjectID); - - return oglc; - } - -JNF_COCOA_ENTER(env); - - CGLSDOps *cglsdo = (CGLSDOps *)dstOps->privOps; - NSView *nsView = (NSView *)cglsdo->peerData; - - if ([ctxinfo->context view] != nsView) { - [ctxinfo->context makeCurrentContext]; - [ctxinfo->context setView: nsView]; - } - - if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) { - // the GL_EXT_framebuffer_object extension is present, so we - // must bind to the default (windowing system provided) - // framebuffer - j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - } - -JNF_COCOA_EXIT(env); - - return oglc; -}*/ - -/** - * This function initializes a native window surface and caches the window - * bounds in the given OGLSDOps. Returns JNI_TRUE if the operation was - * successful; JNI_FALSE otherwise. - */ -/*jboolean -OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo) -{ - J2dTraceLn(J2D_TRACE_INFO, "OGLSD_InitOGLWindow"); - - if (oglsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: ops are null"); - return JNI_FALSE; - } - - CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps; - if (cglsdo == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: cgl ops are null"); - return JNI_FALSE; - } - - AWTView *v = cglsdo->peerData; - if (v == NULL) { - J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: view is invalid"); - return JNI_FALSE; - } - -JNF_COCOA_ENTER(env); - NSRect surfaceBounds = [v bounds]; - oglsdo->drawableType = OGLSD_WINDOW; - oglsdo->isOpaque = JNI_TRUE; - oglsdo->width = surfaceBounds.size.width; - oglsdo->height = surfaceBounds.size.height; -JNF_COCOA_EXIT(env); - - J2dTraceLn2(J2D_TRACE_VERBOSE, " created window: w=%d h=%d", oglsdo->width, oglsdo->height); - - return JNI_TRUE; -} - -void -OGLSD_SwapBuffers(JNIEnv *env, jlong pPeerData) -{ - J2dTraceLn(J2D_TRACE_INFO, "OGLSD_SwapBuffers"); - -JNF_COCOA_ENTER(env); - [[NSOpenGLContext currentContext] flushBuffer]; -JNF_COCOA_EXIT(env); -}*/ - -/*void -OGLSD_Flush(JNIEnv *env) -{ - OGLSDOps *dstOps = OGLRenderQueue_GetCurrentDestination(); - if (dstOps != NULL) { - CGLSDOps *dstCGLOps = (CGLSDOps *)dstOps->privOps; - CGLLayer *layer = (CGLLayer*)dstCGLOps->layer; - if (layer != NULL) { - [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){ - AWT_ASSERT_APPKIT_THREAD; - [layer setNeedsDisplay]; - -#ifdef REMOTELAYER*/ - /* If there's a remote layer (being used for testing) - * then we want to have that also receive the texture. - * First sync. up its dimensions with that of the layer - * we have attached to the local window and tell it that - * it also needs to copy the texture. - */ - /*if (layer.remoteLayer != nil) { - CGLLayer* remoteLayer = layer.remoteLayer; - remoteLayer.target = GL_TEXTURE_2D; - remoteLayer.textureID = layer.textureID; - remoteLayer.textureWidth = layer.textureWidth; - remoteLayer.textureHeight = layer.textureHeight; - [remoteLayer setNeedsDisplay]; - } -#endif*/ /* REMOTELAYER */ - //}]; - //} - //} -//} - -#pragma mark - -#pragma mark "--- MetalSurfaceData methods ---" - -//extern LockFunc OGLSD_Lock; -//extern GetRasInfoFunc OGLSD_GetRasInfo; -//extern UnlockFunc OGLSD_Unlock; -//extern DisposeFunc OGLSD_Dispose; - -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MetalSurfaceData_initOps - (JNIEnv* env, jobject metalsd, - jlong pConfigInfo, jlong pPeerData, jlong layerPtr, - jint xoff, jint yoff, jboolean isOpaque) -{ - //J2dTraceLn(J2D_TRACE_INFO, "MetalSurfaceData_initOps"); - //J2dTraceLn1(J2D_TRACE_INFO, " pPeerData=%p", jlong_to_ptr(pPeerData)); - //J2dTraceLn2(J2D_TRACE_INFO, " xoff=%d, yoff=%d", (int)xoff, (int)yoff); - - //fprintf(stdout, "MetalSurfaceData_initOps\n");fflush(stdout); - MetalSDOps* metalsdo = (MetalSDOps*) - SurfaceData_InitOps(env, metalsd, sizeof(MetalSDOps)); - if (metalsdo == NULL) { - JNU_ThrowOutOfMemoryError(env, "creating native metal ops"); - return; - } - - // TODO : Check use case of below parameters and use them - /*metalsdo->sdOps.Lock = OGLSD_Lock; - metalsdo->sdOps.GetRasInfo = OGLSD_GetRasInfo; - metalsdo->sdOps.Unlock = OGLSD_Unlock; - metalsdo->sdOps.Dispose = OGLSD_Dispose;*/ - - metalsdo->xOffset = xoff; - metalsdo->yOffset = yoff; - metalsdo->isOpaque = isOpaque; - - metalsdo->peerData = (AWTView *)jlong_to_ptr(pPeerData); - metalsdo->layer = (MetalLayer *)jlong_to_ptr(layerPtr); - metalsdo->configInfo = (MetalGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo); - - if (metalsdo->configInfo == NULL) { - free(metalsdo); - JNU_ThrowNullPointerException(env, "Config info is null in initOps"); - } -} - -JNIEXPORT void JNICALL -Java_sun_java2d_opengl_MetalSurfaceData_clearWindow -(JNIEnv *env, jobject metalsd) -{ - //J2dTraceLn(J2D_TRACE_INFO, "MetalSurfaceData_clearWindow"); - - MetalSDOps* metalsdo = (MetalSDOps*) SurfaceData_GetOps(env, metalsd); - - metalsdo->peerData = NULL; - metalsdo->layer = NULL; - metalsdo->mtlTexture = NULL; -} - -#pragma mark - -#pragma mark "--- CGLSurfaceData methods - Mac OS X specific ---" - -// Must be called on the QFT... -JNIEXPORT void JNICALL -Java_sun_java2d_metal_MetalSurfaceData_validate - (JNIEnv *env, jobject jsurfacedata, - jint xoff, jint yoff, jint width, jint height, jboolean isOpaque) -{ - //J2dTraceLn2(J2D_TRACE_INFO, "CGLSurfaceData_validate: w=%d h=%d", width, height); - - MetalSDOps* metalsdo = (MetalSDOps*)SurfaceData_GetOps(env, jsurfacedata); - //oglsdo->needsInit = JNI_TRUE; - metalsdo->xOffset = xoff; - metalsdo->yOffset = yoff; - - metalsdo->width = width; - metalsdo->height = height; - metalsdo->isOpaque = isOpaque; - - // TODO : We need to have similar logic for Metal - /*if (oglsdo->drawableType == OGLSD_WINDOW) { - OGLContext_SetSurfaces(env, ptr_to_jlong(oglsdo), ptr_to_jlong(oglsdo)); - - // we have to explicitly tell the NSOpenGLContext that its target - // drawable has changed size - CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps; - OGLContext *oglc = cglsdo->configInfo->context; - CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo; - -JNF_COCOA_ENTER(env); - [ctxinfo->context update]; -JNF_COCOA_EXIT(env); - }*/ -} - -JNIEXPORT jboolean JNICALL -Java_sun_java2d_metal_MetalSurfaceData_initTexture -(JNIEnv *env, jobject oglsd, - jlong pData, jboolean isOpaque, - jint width, jint height) -{ - MetalSDOps* metalsdo = (MetalSDOps *)jlong_to_ptr(pData); - //fprintf(stdout, "MetalSurfaceData_initTexture\n");fflush(stdout); - // OFFLINE TEXTURE - MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init]; - - // Indicate that each pixel has a blue, green, red, and alpha channel, where each channel is - // an 8-bit unsigned normalized value (i.e. 0 maps to 0.0 and 255 maps to 1.0) - textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm; - textureDescriptor.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget; - - // Set the pixel dimensions of the texture - textureDescriptor.width = width; - textureDescriptor.height = height; - - // Create the texture from the device by using the descriptor - metalsdo->mtlTexture = [metalsdo->configInfo->device newTextureWithDescriptor:textureDescriptor]; - - metalsdo->width = width; - metalsdo->height = height; - metalsdo->isOpaque = isOpaque; - - // TODO : We may need to refactor the code related shader initialization - MetalGraphicsConfigInfo* pInfo = - (MetalGraphicsConfigInfo*)jlong_to_ptr(metalsdo->configInfo); - if ((pInfo == NULL)) { - return -1; - } - - MetalLayer* mtlLayer = jlong_to_ptr(metalsdo->layer); - - //mtlLayer.device = pInfo->device; - mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; - - //mtlLayer.commandQueue = pInfo->commandQueue; - - /* - // Load shaders. - NSError *error = nil; - id mtlLibrary = [metalsdo->configInfo->device newLibraryWithFile: @"/tmp/MyShader.metallib" error:&error]; - if (!mtlLibrary) { - NSLog(@"Failed to load library. error %@", error); - //exit(0); - } - - //create a vertex and fragment function object - id vertexProgram = [mtlLibrary newFunctionWithName:@"vertexShader"]; - id fragmentProgram = [mtlLibrary newFunctionWithName:@"fragmentShader"]; - - MTLRenderPipelineDescriptor* mtlRenderPipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; - - //assign the vertex and fragment functions to the descriptor - [mtlRenderPipelineDescriptor setVertexFunction:vertexProgram]; - [mtlRenderPipelineDescriptor setFragmentFunction:fragmentProgram]; - - //specify the target-texture pixel format - - mtlRenderPipelineDescriptor.colorAttachments[0].pixelFormat=MTLPixelFormatBGRA8Unorm; - - //create the Rendering Pipeline Object - metalsdo->renderPipelineState = [mtlLayer.device newRenderPipelineStateWithDescriptor:mtlRenderPipelineDescriptor error:nil];*/ - - return JNI_TRUE; -}