src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MetalSurfaceData.m
branchmetal-prototype-branch
changeset 57416 e153174dba06
parent 57400 978ffc56771f
child 57417 28582d575a98
equal deleted inserted replaced
57400:978ffc56771f 57416:e153174dba06
     1 /*
       
     2  * Copyright (c) 2019, 2019, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 #import <stdlib.h>
       
    27 
       
    28 #import "sun_java2d_metal_MetalSurfaceData.h"
       
    29 
       
    30 #import "jni_util.h"
       
    31 #import "MetalRenderQueue.h"
       
    32 #import "MetalGraphicsConfig.h"
       
    33 #import "MetalSurfaceData.h"
       
    34 #import "ThreadUtilities.h"
       
    35 
       
    36 /* JDK's glext.h is already included and will prevent the Apple glext.h
       
    37  * being included, so define the externs directly
       
    38  */
       
    39 /*extern void glBindFramebufferEXT(GLenum target, GLuint framebuffer);
       
    40 extern CGLError CGLTexImageIOSurface2D(
       
    41         CGLContextObj ctx, GLenum target, GLenum internal_format,
       
    42         GLsizei width, GLsizei height, GLenum format, GLenum type,
       
    43         IOSurfaceRef ioSurface, GLuint plane);*/
       
    44 
       
    45 /**
       
    46  * The methods in this file implement the native windowing system specific
       
    47  * layer (CGL) for the OpenGL-based Java 2D pipeline.
       
    48  */
       
    49 
       
    50 #pragma mark -
       
    51 #pragma mark "--- Mac OS X specific methods for GL pipeline ---"
       
    52 
       
    53 // TODO: hack that's called from OGLRenderQueue to test out unlockFocus behavior
       
    54 /*#if 0
       
    55 void
       
    56 OGLSD_UnlockFocus(OGLContext *oglc, OGLSDOps *dstOps)
       
    57 {
       
    58     CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
       
    59     CGLSDOps *cglsdo = (CGLSDOps *)dstOps->privOps;
       
    60     fprintf(stderr, "about to unlock focus: %p %p\n",
       
    61             cglsdo->peerData, ctxinfo->context);
       
    62 
       
    63     NSOpenGLView *nsView = cglsdo->peerData;
       
    64     if (nsView != NULL) {
       
    65 JNF_COCOA_ENTER(env);
       
    66         [nsView unlockFocus];
       
    67 JNF_COCOA_EXIT(env);
       
    68     }
       
    69 }
       
    70 #endif*/
       
    71 
       
    72 /**
       
    73  * Makes the given context current to its associated "scratch" surface.  If
       
    74  * the operation is successful, this method will return JNI_TRUE; otherwise,
       
    75  * returns JNI_FALSE.
       
    76  */
       
    77 /*static jboolean
       
    78 CGLSD_MakeCurrentToScratch(JNIEnv *env, OGLContext *oglc)
       
    79 {
       
    80     J2dTraceLn(J2D_TRACE_INFO, "CGLSD_MakeCurrentToScratch");
       
    81 
       
    82     if (oglc == NULL) {
       
    83         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
    84                       "CGLSD_MakeCurrentToScratch: context is null");
       
    85         return JNI_FALSE;
       
    86     }
       
    87 
       
    88 JNF_COCOA_ENTER(env);
       
    89 
       
    90     CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
       
    91 #if USE_NSVIEW_FOR_SCRATCH
       
    92     [ctxinfo->context makeCurrentContext];
       
    93     [ctxinfo->context setView: ctxinfo->scratchSurface];
       
    94 #else
       
    95     [ctxinfo->context clearDrawable];
       
    96     [ctxinfo->context makeCurrentContext];
       
    97     [ctxinfo->context setPixelBuffer: ctxinfo->scratchSurface
       
    98             cubeMapFace: 0
       
    99             mipMapLevel: 0
       
   100             currentVirtualScreen: [ctxinfo->context currentVirtualScreen]];
       
   101 #endif
       
   102 
       
   103 JNF_COCOA_EXIT(env);
       
   104 
       
   105     return JNI_TRUE;
       
   106 }*/
       
   107 
       
   108 /**
       
   109  * This function disposes of any native windowing system resources associated
       
   110  * with this surface.
       
   111  */
       
   112 /*void
       
   113 OGLSD_DestroyOGLSurface(JNIEnv *env, OGLSDOps *oglsdo)
       
   114 {
       
   115     J2dTraceLn(J2D_TRACE_INFO, "OGLSD_DestroyOGLSurface");
       
   116 
       
   117 JNF_COCOA_ENTER(env);
       
   118 
       
   119     CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
       
   120     if (oglsdo->drawableType == OGLSD_WINDOW) {
       
   121         // detach the NSView from the NSOpenGLContext
       
   122         CGLGraphicsConfigInfo *cglInfo = cglsdo->configInfo;
       
   123         OGLContext *oglc = cglInfo->context;
       
   124         CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
       
   125         [ctxinfo->context clearDrawable];
       
   126     }
       
   127 
       
   128     oglsdo->drawableType = OGLSD_UNDEFINED;
       
   129 
       
   130 JNF_COCOA_EXIT(env);
       
   131 }*/
       
   132 
       
   133 /**
       
   134  * Returns a pointer (as a jlong) to the native CGLGraphicsConfigInfo
       
   135  * associated with the given OGLSDOps.  This method can be called from
       
   136  * shared code to retrieve the native GraphicsConfig data in a platform-
       
   137  * independent manner.
       
   138  */
       
   139 /*jlong
       
   140 OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo)
       
   141 {
       
   142     J2dTraceLn(J2D_TRACE_INFO, "OGLSD_GetNativeConfigInfo");
       
   143 
       
   144     if (oglsdo == NULL) {
       
   145         J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: ops are null");
       
   146         return 0L;
       
   147     }
       
   148 
       
   149     CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
       
   150     if (cglsdo == NULL) {
       
   151         J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: cgl ops are null");
       
   152         return 0L;
       
   153     }
       
   154 
       
   155     return ptr_to_jlong(cglsdo->configInfo);
       
   156 }*/
       
   157 
       
   158 /**
       
   159  * Makes the given GraphicsConfig's context current to its associated
       
   160  * "scratch" surface.  If there is a problem making the context current,
       
   161  * this method will return NULL; otherwise, returns a pointer to the
       
   162  * OGLContext that is associated with the given GraphicsConfig.
       
   163  */
       
   164 /*OGLContext *
       
   165 OGLSD_SetScratchSurface(JNIEnv *env, jlong pConfigInfo)
       
   166 {
       
   167     J2dTraceLn(J2D_TRACE_INFO, "OGLSD_SetScratchContext");
       
   168 
       
   169     CGLGraphicsConfigInfo *cglInfo = (CGLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
       
   170     if (cglInfo == NULL) {
       
   171         J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: cgl config info is null");
       
   172         return NULL;
       
   173     }
       
   174 
       
   175     OGLContext *oglc = cglInfo->context;
       
   176     if (oglc == NULL) {
       
   177         J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: ogl context is null");
       
   178         return NULL;
       
   179     }
       
   180 
       
   181     CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
       
   182 
       
   183 JNF_COCOA_ENTER(env);
       
   184 
       
   185     // avoid changing the context's target view whenever possible, since
       
   186     // calling setView causes flickering; as long as our context is current
       
   187     // to some view, it's not necessary to switch to the scratch surface
       
   188     if ([ctxinfo->context view] == nil) {
       
   189         // it seems to be necessary to explicitly flush between context changes
       
   190         OGLContext *currentContext = OGLRenderQueue_GetCurrentContext();
       
   191         if (currentContext != NULL) {
       
   192             j2d_glFlush();
       
   193         }
       
   194 
       
   195         if (!CGLSD_MakeCurrentToScratch(env, oglc)) {
       
   196             return NULL;
       
   197         }
       
   198     // make sure our context is current
       
   199     } else if ([NSOpenGLContext currentContext] != ctxinfo->context) {
       
   200         [ctxinfo->context makeCurrentContext];
       
   201     }
       
   202 
       
   203     if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) {
       
   204         // the GL_EXT_framebuffer_object extension is present, so this call
       
   205         // will ensure that we are bound to the scratch surface (and not
       
   206         // some other framebuffer object)
       
   207         j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
       
   208     }
       
   209 
       
   210 JNF_COCOA_EXIT(env);
       
   211 
       
   212     return oglc;
       
   213 }*/
       
   214 
       
   215 /**
       
   216  * Makes a context current to the given source and destination
       
   217  * surfaces.  If there is a problem making the context current, this method
       
   218  * will return NULL; otherwise, returns a pointer to the OGLContext that is
       
   219  * associated with the destination surface.
       
   220  */
       
   221 /*OGLContext *
       
   222 OGLSD_MakeOGLContextCurrent(JNIEnv *env, OGLSDOps *srcOps, OGLSDOps *dstOps)
       
   223 {
       
   224     J2dTraceLn(J2D_TRACE_INFO, "OGLSD_MakeOGLContextCurrent");
       
   225 
       
   226     CGLSDOps *dstCGLOps = (CGLSDOps *)dstOps->privOps;
       
   227 
       
   228     J2dTraceLn4(J2D_TRACE_VERBOSE, "  src: %d %p dst: %d %p", srcOps->drawableType, srcOps, dstOps->drawableType, dstOps);
       
   229 
       
   230     OGLContext *oglc = dstCGLOps->configInfo->context;
       
   231     if (oglc == NULL) {
       
   232         J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_MakeOGLContextCurrent: context is null");
       
   233         return NULL;
       
   234     }
       
   235 
       
   236     CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
       
   237 
       
   238     // it seems to be necessary to explicitly flush between context changes
       
   239     OGLContext *currentContext = OGLRenderQueue_GetCurrentContext();
       
   240     if (currentContext != NULL) {
       
   241         j2d_glFlush();
       
   242     }
       
   243 
       
   244     if (dstOps->drawableType == OGLSD_FBOBJECT) {
       
   245         // first make sure we have a current context (if the context isn't
       
   246         // already current to some drawable, we will make it current to
       
   247         // its scratch surface)
       
   248         if (oglc != currentContext) {
       
   249             if (!CGLSD_MakeCurrentToScratch(env, oglc)) {
       
   250                 return NULL;
       
   251             }
       
   252         }
       
   253 
       
   254         // now bind to the fbobject associated with the destination surface;
       
   255         // this means that all rendering will go into the fbobject destination
       
   256         // (note that we unbind the currently bound texture first; this is
       
   257         // recommended procedure when binding an fbobject)
       
   258         j2d_glBindTexture(GL_TEXTURE_2D, 0);
       
   259         j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, dstOps->fbobjectID);
       
   260 
       
   261         return oglc;
       
   262     }
       
   263 
       
   264 JNF_COCOA_ENTER(env);
       
   265 
       
   266     CGLSDOps *cglsdo = (CGLSDOps *)dstOps->privOps;
       
   267     NSView *nsView = (NSView *)cglsdo->peerData;
       
   268 
       
   269     if ([ctxinfo->context view] != nsView) {
       
   270         [ctxinfo->context makeCurrentContext];
       
   271         [ctxinfo->context setView: nsView];
       
   272     }
       
   273 
       
   274     if (OGLC_IS_CAP_PRESENT(oglc, CAPS_EXT_FBOBJECT)) {
       
   275         // the GL_EXT_framebuffer_object extension is present, so we
       
   276         // must bind to the default (windowing system provided)
       
   277         // framebuffer
       
   278         j2d_glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
       
   279     }
       
   280 
       
   281 JNF_COCOA_EXIT(env);
       
   282 
       
   283     return oglc;
       
   284 }*/
       
   285 
       
   286 /**
       
   287  * This function initializes a native window surface and caches the window
       
   288  * bounds in the given OGLSDOps.  Returns JNI_TRUE if the operation was
       
   289  * successful; JNI_FALSE otherwise.
       
   290  */
       
   291 /*jboolean
       
   292 OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo)
       
   293 {
       
   294     J2dTraceLn(J2D_TRACE_INFO, "OGLSD_InitOGLWindow");
       
   295 
       
   296     if (oglsdo == NULL) {
       
   297         J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: ops are null");
       
   298         return JNI_FALSE;
       
   299     }
       
   300 
       
   301     CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
       
   302     if (cglsdo == NULL) {
       
   303         J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: cgl ops are null");
       
   304         return JNI_FALSE;
       
   305     }
       
   306 
       
   307     AWTView *v = cglsdo->peerData;
       
   308     if (v == NULL) {
       
   309         J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_InitOGLWindow: view is invalid");
       
   310         return JNI_FALSE;
       
   311     }
       
   312 
       
   313 JNF_COCOA_ENTER(env);
       
   314     NSRect surfaceBounds = [v bounds];
       
   315     oglsdo->drawableType = OGLSD_WINDOW;
       
   316     oglsdo->isOpaque = JNI_TRUE;
       
   317     oglsdo->width = surfaceBounds.size.width;
       
   318     oglsdo->height = surfaceBounds.size.height;
       
   319 JNF_COCOA_EXIT(env);
       
   320 
       
   321     J2dTraceLn2(J2D_TRACE_VERBOSE, "  created window: w=%d h=%d", oglsdo->width, oglsdo->height);
       
   322 
       
   323     return JNI_TRUE;
       
   324 }
       
   325 
       
   326 void
       
   327 OGLSD_SwapBuffers(JNIEnv *env, jlong pPeerData)
       
   328 {
       
   329     J2dTraceLn(J2D_TRACE_INFO, "OGLSD_SwapBuffers");
       
   330 
       
   331 JNF_COCOA_ENTER(env);
       
   332     [[NSOpenGLContext currentContext] flushBuffer];
       
   333 JNF_COCOA_EXIT(env);
       
   334 }*/
       
   335 
       
   336 /*void
       
   337 OGLSD_Flush(JNIEnv *env)
       
   338 {
       
   339     OGLSDOps *dstOps = OGLRenderQueue_GetCurrentDestination();
       
   340     if (dstOps != NULL) {
       
   341         CGLSDOps *dstCGLOps = (CGLSDOps *)dstOps->privOps;
       
   342         CGLLayer *layer = (CGLLayer*)dstCGLOps->layer;
       
   343         if (layer != NULL) {
       
   344             [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
       
   345                 AWT_ASSERT_APPKIT_THREAD;
       
   346                 [layer setNeedsDisplay];
       
   347 
       
   348 #ifdef REMOTELAYER*/
       
   349                 /* If there's a remote layer (being used for testing)
       
   350                  * then we want to have that also receive the texture.
       
   351                  * First sync. up its dimensions with that of the layer
       
   352                  * we have attached to the local window and tell it that
       
   353                  * it also needs to copy the texture.
       
   354                  */
       
   355                 /*if (layer.remoteLayer != nil) {
       
   356                     CGLLayer* remoteLayer = layer.remoteLayer;
       
   357                     remoteLayer.target = GL_TEXTURE_2D;
       
   358                     remoteLayer.textureID = layer.textureID;
       
   359                     remoteLayer.textureWidth = layer.textureWidth;
       
   360                     remoteLayer.textureHeight = layer.textureHeight;
       
   361                     [remoteLayer setNeedsDisplay];
       
   362                 }
       
   363 #endif*/ /* REMOTELAYER */
       
   364             //}];
       
   365         //}
       
   366     //}
       
   367 //}
       
   368 
       
   369 #pragma mark -
       
   370 #pragma mark "--- MetalSurfaceData methods ---"
       
   371 
       
   372 //extern LockFunc        OGLSD_Lock;
       
   373 //extern GetRasInfoFunc  OGLSD_GetRasInfo;
       
   374 //extern UnlockFunc      OGLSD_Unlock;
       
   375 //extern DisposeFunc     OGLSD_Dispose;
       
   376 
       
   377 JNIEXPORT void JNICALL
       
   378 Java_sun_java2d_metal_MetalSurfaceData_initOps
       
   379     (JNIEnv* env, jobject metalsd,
       
   380      jlong pConfigInfo, jlong pPeerData, jlong layerPtr,
       
   381      jint xoff, jint yoff, jboolean isOpaque)
       
   382 {
       
   383     //J2dTraceLn(J2D_TRACE_INFO, "MetalSurfaceData_initOps");
       
   384     //J2dTraceLn1(J2D_TRACE_INFO, "  pPeerData=%p", jlong_to_ptr(pPeerData));
       
   385     //J2dTraceLn2(J2D_TRACE_INFO, "  xoff=%d, yoff=%d", (int)xoff, (int)yoff);
       
   386 
       
   387     //fprintf(stdout, "MetalSurfaceData_initOps\n");fflush(stdout);
       
   388     MetalSDOps* metalsdo = (MetalSDOps*)
       
   389         SurfaceData_InitOps(env, metalsd, sizeof(MetalSDOps));
       
   390     if (metalsdo == NULL) {
       
   391         JNU_ThrowOutOfMemoryError(env, "creating native metal ops");
       
   392         return;
       
   393     }
       
   394 
       
   395     // TODO : Check use case of below parameters and use them
       
   396     /*metalsdo->sdOps.Lock               = OGLSD_Lock;
       
   397     metalsdo->sdOps.GetRasInfo         = OGLSD_GetRasInfo;
       
   398     metalsdo->sdOps.Unlock             = OGLSD_Unlock;
       
   399     metalsdo->sdOps.Dispose            = OGLSD_Dispose;*/
       
   400 
       
   401     metalsdo->xOffset = xoff;
       
   402     metalsdo->yOffset = yoff;
       
   403     metalsdo->isOpaque = isOpaque;
       
   404 
       
   405     metalsdo->peerData = (AWTView *)jlong_to_ptr(pPeerData);
       
   406     metalsdo->layer = (MetalLayer *)jlong_to_ptr(layerPtr);
       
   407     metalsdo->configInfo = (MetalGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
       
   408 
       
   409     if (metalsdo->configInfo == NULL) {
       
   410         free(metalsdo);
       
   411         JNU_ThrowNullPointerException(env, "Config info is null in initOps");
       
   412     }
       
   413 }
       
   414 
       
   415 JNIEXPORT void JNICALL
       
   416 Java_sun_java2d_opengl_MetalSurfaceData_clearWindow
       
   417 (JNIEnv *env, jobject metalsd)
       
   418 {
       
   419     //J2dTraceLn(J2D_TRACE_INFO, "MetalSurfaceData_clearWindow");
       
   420 
       
   421     MetalSDOps* metalsdo = (MetalSDOps*) SurfaceData_GetOps(env, metalsd);
       
   422 
       
   423     metalsdo->peerData = NULL;
       
   424     metalsdo->layer = NULL;
       
   425     metalsdo->mtlTexture = NULL;
       
   426 }
       
   427 
       
   428 #pragma mark -
       
   429 #pragma mark "--- CGLSurfaceData methods - Mac OS X specific ---"
       
   430 
       
   431 // Must be called on the QFT...
       
   432 JNIEXPORT void JNICALL
       
   433 Java_sun_java2d_metal_MetalSurfaceData_validate
       
   434     (JNIEnv *env, jobject jsurfacedata,
       
   435      jint xoff, jint yoff, jint width, jint height, jboolean isOpaque)
       
   436 {
       
   437     //J2dTraceLn2(J2D_TRACE_INFO, "CGLSurfaceData_validate: w=%d h=%d", width, height);
       
   438 
       
   439     MetalSDOps* metalsdo = (MetalSDOps*)SurfaceData_GetOps(env, jsurfacedata);
       
   440     //oglsdo->needsInit = JNI_TRUE;
       
   441     metalsdo->xOffset = xoff;
       
   442     metalsdo->yOffset = yoff;
       
   443 
       
   444     metalsdo->width = width;
       
   445     metalsdo->height = height;
       
   446     metalsdo->isOpaque = isOpaque;
       
   447 
       
   448     // TODO : We need to have similar logic for Metal
       
   449     /*if (oglsdo->drawableType == OGLSD_WINDOW) {
       
   450         OGLContext_SetSurfaces(env, ptr_to_jlong(oglsdo), ptr_to_jlong(oglsdo));
       
   451 
       
   452         // we have to explicitly tell the NSOpenGLContext that its target
       
   453         // drawable has changed size
       
   454         CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
       
   455         OGLContext *oglc = cglsdo->configInfo->context;
       
   456         CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
       
   457 
       
   458 JNF_COCOA_ENTER(env);
       
   459         [ctxinfo->context update];
       
   460 JNF_COCOA_EXIT(env);
       
   461     }*/
       
   462 }
       
   463 
       
   464 JNIEXPORT jboolean JNICALL
       
   465 Java_sun_java2d_metal_MetalSurfaceData_initTexture
       
   466 (JNIEnv *env, jobject oglsd,
       
   467  jlong pData, jboolean isOpaque,
       
   468  jint width, jint height)
       
   469 {
       
   470     MetalSDOps* metalsdo = (MetalSDOps *)jlong_to_ptr(pData);
       
   471     //fprintf(stdout, "MetalSurfaceData_initTexture\n");fflush(stdout);
       
   472     // OFFLINE TEXTURE
       
   473     MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init];
       
   474     
       
   475     // Indicate that each pixel has a blue, green, red, and alpha channel, where each channel is
       
   476     // an 8-bit unsigned normalized value (i.e. 0 maps to 0.0 and 255 maps to 1.0)
       
   477     textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm;
       
   478     textureDescriptor.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
       
   479     
       
   480     // Set the pixel dimensions of the texture
       
   481     textureDescriptor.width = width;
       
   482     textureDescriptor.height = height;
       
   483     
       
   484     // Create the texture from the device by using the descriptor
       
   485     metalsdo->mtlTexture = [metalsdo->configInfo->device newTextureWithDescriptor:textureDescriptor];
       
   486     
       
   487     metalsdo->width = width;
       
   488     metalsdo->height = height;
       
   489     metalsdo->isOpaque = isOpaque;
       
   490     
       
   491     // TODO : We may need to refactor the code related shader initialization
       
   492     MetalGraphicsConfigInfo* pInfo =
       
   493     (MetalGraphicsConfigInfo*)jlong_to_ptr(metalsdo->configInfo);
       
   494     if ((pInfo == NULL)) {
       
   495         return -1;
       
   496     }
       
   497     
       
   498     MetalLayer* mtlLayer = jlong_to_ptr(metalsdo->layer);
       
   499     
       
   500     //mtlLayer.device = pInfo->device;
       
   501     mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
       
   502     
       
   503     //mtlLayer.commandQueue = pInfo->commandQueue;
       
   504     
       
   505    /* 
       
   506     // Load shaders.
       
   507     NSError *error = nil;
       
   508     id<MTLLibrary> mtlLibrary = [metalsdo->configInfo->device newLibraryWithFile: @"/tmp/MyShader.metallib" error:&error];
       
   509     if (!mtlLibrary) {
       
   510         NSLog(@"Failed to load library. error %@", error);
       
   511         //exit(0);
       
   512     }
       
   513     
       
   514     //create a vertex and fragment function object
       
   515     id<MTLFunction> vertexProgram = [mtlLibrary newFunctionWithName:@"vertexShader"];
       
   516     id<MTLFunction> fragmentProgram = [mtlLibrary newFunctionWithName:@"fragmentShader"];
       
   517     
       
   518     MTLRenderPipelineDescriptor* mtlRenderPipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
       
   519     
       
   520     //assign the vertex and fragment functions to the descriptor
       
   521     [mtlRenderPipelineDescriptor setVertexFunction:vertexProgram];
       
   522     [mtlRenderPipelineDescriptor setFragmentFunction:fragmentProgram];
       
   523     
       
   524     //specify the target-texture pixel format
       
   525 
       
   526     mtlRenderPipelineDescriptor.colorAttachments[0].pixelFormat=MTLPixelFormatBGRA8Unorm;
       
   527     
       
   528     //create the Rendering Pipeline Object
       
   529     metalsdo->renderPipelineState = [mtlLayer.device newRenderPipelineStateWithDescriptor:mtlRenderPipelineDescriptor error:nil];*/
       
   530     
       
   531     return JNI_TRUE;
       
   532 }