--- /dev/null 2019-03-05 14:31:17.000000000 +0300 +++ new/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLSurfaceDataBase.m 2019-03-05 14:31:17.000000000 +0300 @@ -0,0 +1,360 @@ +/* + * Copyright (c) 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. + */ + +#ifndef HEADLESS + +#include + +#include "sun_java2d_metal_MTLSurfaceData.h" + +#include "jlong.h" +#include "jni_util.h" +#include "MTLSurfaceData.h" +#import "ThreadUtilities.h" + +/** + * The following methods are implemented in the windowing system (i.e. GLX + * and WGL) source files. + */ +extern jlong MTLSD_GetNativeConfigInfo(MTLSDOps *mtlsdo); +extern jboolean MTLSD_InitMTLWindow(JNIEnv *env, MTLSDOps *mtlsdo); +extern void MTLSD_DestroyMTLSurface(JNIEnv *env, MTLSDOps *mtlsdo); + +void MTLSD_SetNativeDimensions(JNIEnv *env, BMTLSDOps *mtlsdo, jint w, jint h); + +/** + * This table contains the "pixel formats" for all system memory surfaces + * that OpenGL is capable of handling, indexed by the "PF_" constants defined + * in MTLSurfaceData.java. These pixel formats contain information that is + * passed to OpenGL when copying from a system memory ("Sw") surface to + * an OpenGL "Surface" (via glDrawPixels()) or "Texture" (via glTexImage2D()). + */ +MTLPixelFormat MTPixelFormats[] = {}; + +/** + * Given a starting value and a maximum limit, returns the first power-of-two + * greater than the starting value. If the resulting value is greater than + * the maximum limit, zero is returned. + */ +jint +MTLSD_NextPowerOfTwo(jint val, jint max) +{ + jint i; + + if (val > max) { + return 0; + } + + for (i = 1; i < val; i *= 2); + + return i; +} + +/** + * Returns true if both given dimensions are a power of two. + */ +static jboolean +MTLSD_IsPowerOfTwo(jint width, jint height) +{ + return (((width & (width-1)) | (height & (height-1))) == 0); +} + +/** + * Initializes an OpenGL texture object. + * + * If the isOpaque parameter is JNI_FALSE, then the texture will have a + * full alpha channel; otherwise, the texture will be opaque (this can + * help save VRAM when translucency is not needed). + * + * If the GL_ARB_texture_non_power_of_two extension is present (texNonPow2 + * is JNI_TRUE), the actual texture is allowed to have non-power-of-two + * dimensions, and therefore width==textureWidth and height==textureHeight. + * + * Failing that, if the GL_ARB_texture_rectangle extension is present + * (texRect is JNI_TRUE), the actual texture is allowed to have + * non-power-of-two dimensions, except that instead of using the usual + * GL_TEXTURE_2D target, we need to use the GL_TEXTURE_RECTANGLE_ARB target. + * Note that the GL_REPEAT wrapping mode is not allowed with this target, + * so if that mode is needed (e.g. as is the case in the TexturePaint code) + * one should pass JNI_FALSE to avoid using this extension. Also note that + * when the texture target is GL_TEXTURE_RECTANGLE_ARB, texture coordinates + * must be specified in the range [0,width] and [0,height] rather than + * [0,1] as is the case with the usual GL_TEXTURE_2D target (so take care)! + * + * Otherwise, the actual texture must have power-of-two dimensions, and + * therefore the textureWidth and textureHeight will be the next + * power-of-two greater than (or equal to) the requested width and height. + */ +static jboolean +MTLSD_InitTextureObject(MTLSDOps *mtlsdo, + jboolean isOpaque, + jboolean texNonPow2, jboolean texRect, + jint width, jint height) +{ + //TODO + J2dTraceNotImplPrimitive("MTLSD_InitTextureObject"); + return JNI_TRUE; +} + +/** + * Initializes an MTL texture, using the given width and height as + * a guide. See MTLSD_InitTextureObject() for more information. + */ +JNIEXPORT jboolean JNICALL +Java_sun_java2d_metal_MTLSurfaceDataBase_initTexture + (JNIEnv *env, jobject mtlsd, + jlong pData, jboolean isOpaque, + jboolean texNonPow2, jboolean texRect, + jint width, jint height) +{ + BMTLSDOps *mtlsdo = (BMTLSDOps *)jlong_to_ptr(pData); + J2dTraceLn2(J2D_TRACE_INFO, "MTLSurfaceData_initTexture: w=%d h=%d", + width, height); + + if (mtlsdo == NULL) { + J2dRlsTraceLn(J2D_TRACE_ERROR, + "MTLSurfaceData_initTexture: ops are null"); + return JNI_FALSE; + } + + /* + * We only use the GL_ARB_texture_rectangle extension if it is available + * and the requested bounds are not pow2 (it is probably faster to use + * GL_TEXTURE_2D for pow2 textures, and besides, our TexturePaint + * code relies on GL_REPEAT, which is not allowed for + * GL_TEXTURE_RECTANGLE_ARB targets). + */ + texRect = texRect && !MTLSD_IsPowerOfTwo(width, height); + + if (!MTLSD_InitTextureObject(mtlsdo, isOpaque, texNonPow2, texRect, + width, height)) + { + J2dRlsTraceLn(J2D_TRACE_ERROR, + "MTLSurfaceData_initTexture: could not init texture object"); + return JNI_FALSE; + } + + MTLSD_SetNativeDimensions(env, mtlsdo, + mtlsdo->textureWidth, mtlsdo->textureHeight); + + mtlsdo->drawableType = MTLSD_TEXTURE; + // other fields (e.g. width, height) are set in MTLSD_InitTextureObject() + + return JNI_TRUE; +} + +/** + * Initializes a framebuffer object, using the given width and height as + * a guide. See MTLSD_InitTextureObject() and MTLSD_InitFBObject() + * for more information. + */ +JNIEXPORT jboolean JNICALL +Java_sun_java2d_metal_MTLSurfaceDataBase_initFBObject + (JNIEnv *env, jobject mtlsd, + jlong pData, jboolean isOpaque, + jboolean texNonPow2, jboolean texRect, + jint width, jint height) +{ + + BMTLSDOps *bmtlsdo = (BMTLSDOps *)jlong_to_ptr(pData); + + if (bmtlsdo == NULL) { + J2dRlsTraceLn(J2D_TRACE_ERROR, + "MTLSurfaceData_initFBObject: BMTLSDOps are null"); + return JNI_FALSE; + } + + MTLSDOps *mtlsdo = (MTLSDOps *)bmtlsdo->privOps; + + if (mtlsdo == NULL) { + J2dRlsTraceLn(J2D_TRACE_ERROR, + "MTLSurfaceData_initFBObject: MTLSDOps are null"); + return JNI_FALSE; + } + + J2dTraceLn2(J2D_TRACE_INFO, + "MTLSurfaceData_initFBObject: w=%d h=%d", + width, height); + + + + if (mtlsdo->configInfo) { + if (mtlsdo->configInfo->context != NULL) { + MTLContext* ctx = mtlsdo->configInfo->context; + if (ctx == NULL) { + NSLog(@"ctx is NULL"); + } else { + [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ + MTLTextureDescriptor *textureDescriptor = + [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatRGBA8Unorm + width: width + height: height + mipmapped: NO]; + ctx->mtlFrameBuffer = [[ctx->mtlDevice newTextureWithDescriptor: textureDescriptor] retain]; + }]; + } + } + } + + + bmtlsdo->drawableType = MTLSD_FBOBJECT; + + return JNI_TRUE; +} + +/** + * Initializes a surface in the backbuffer of a given double-buffered + * onscreen window for use in a BufferStrategy.Flip situation. The bounds of + * the backbuffer surface should always be kept in sync with the bounds of + * the underlying native window. + */ +JNIEXPORT jboolean JNICALL +Java_sun_java2d_metal_MTLSurfaceDataBase_initFlipBackbuffer + (JNIEnv *env, jobject mtlsd, + jlong pData) +{ + //TODO + J2dTraceNotImplPrimitive("MTLSurfaceDataBase_initFlipBackbuffer"); + MTLSDOps *mtlsdo = (MTLSDOps *)jlong_to_ptr(pData); + + J2dTraceLn(J2D_TRACE_INFO, "MTLSurfaceData_initFlipBackbuffer"); + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_sun_java2d_metal_MTLSurfaceDataBase_getTextureTarget + (JNIEnv *env, jobject mtlsd, + jlong pData) +{ + //TODO + J2dTraceNotImplPrimitive("MTLSurfaceDataBase_getTextureTarget"); + MTLSDOps *mtlsdo = (MTLSDOps *)jlong_to_ptr(pData); + + J2dTraceLn(J2D_TRACE_INFO, "MTLSurfaceData_getTextureTarget"); + + return 0; +} + +JNIEXPORT jint JNICALL +Java_sun_java2d_metal_MTLSurfaceDataBase_getTextureID + (JNIEnv *env, jobject mtlsd, + jlong pData) +{ + //TODO + J2dTraceNotImplPrimitive("MTLSurfaceDataBase_getTextureID"); + return 0; +} + +/** + * Initializes nativeWidth/Height fields of the surfaceData object with + * passed arguments. + */ +void +MTLSD_SetNativeDimensions(JNIEnv *env, BMTLSDOps *mtlsdo, + jint width, jint height) +{ + jobject sdObject; + + sdObject = (*env)->NewLocalRef(env, mtlsdo->sdOps.sdObject); + if (sdObject == NULL) { + return; + } + + JNU_SetFieldByName(env, NULL, sdObject, "nativeWidth", "I", width); + if (!((*env)->ExceptionOccurred(env))) { + JNU_SetFieldByName(env, NULL, sdObject, "nativeHeight", "I", height); + } + + (*env)->DeleteLocalRef(env, sdObject); +} + +/** + * Deletes native OpenGL resources associated with this surface. + */ +void +MTLSD_Delete(JNIEnv *env, BMTLSDOps *mtlsdo) +{ + //TODO + J2dTraceNotImplPrimitive("MTLSD_Delete"); + J2dTraceLn1(J2D_TRACE_INFO, "MTLSD_Delete: type=%d", + mtlsdo->drawableType); +} + +/** + * This is the implementation of the general DisposeFunc defined in + * SurfaceData.h and used by the Disposer mechanism. It first flushes all + * native OpenGL resources and then frees any memory allocated within the + * native MTLSDOps structure. + */ +void +MTLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops) +{ + MTLSDOps *mtlsdo = (MTLSDOps *)ops; + jlong pConfigInfo = MTLSD_GetNativeConfigInfo(mtlsdo); + + JNU_CallStaticMethodByName(env, NULL, "sun/java2d/metal/MTLSurfaceData", + "dispose", "(JJ)V", + ptr_to_jlong(ops), pConfigInfo); +} + +/** + * This is the implementation of the general surface LockFunc defined in + * SurfaceData.h. + */ +jint +MTLSD_Lock(JNIEnv *env, + SurfaceDataOps *ops, + SurfaceDataRasInfo *pRasInfo, + jint lockflags) +{ + JNU_ThrowInternalError(env, "MTLSD_Lock not implemented!"); + return SD_FAILURE; +} + +/** + * This is the implementation of the general GetRasInfoFunc defined in + * SurfaceData.h. + */ +void +MTLSD_GetRasInfo(JNIEnv *env, + SurfaceDataOps *ops, + SurfaceDataRasInfo *pRasInfo) +{ + JNU_ThrowInternalError(env, "MTLSD_GetRasInfo not implemented!"); +} + +/** + * This is the implementation of the general surface UnlockFunc defined in + * SurfaceData.h. + */ +void +MTLSD_Unlock(JNIEnv *env, + SurfaceDataOps *ops, + SurfaceDataRasInfo *pRasInfo) +{ + JNU_ThrowInternalError(env, "MTLSD_Unlock not implemented!"); +} + +#endif /* !HEADLESS */