src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLContext.m
branchmetal-prototype-branch
changeset 57416 e153174dba06
child 57472 5c986f86899e
equal deleted inserted replaced
57400:978ffc56771f 57416:e153174dba06
       
     1 /*
       
     2  * Copyright (c) 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 #ifndef HEADLESS
       
    27 
       
    28 #include <stdlib.h>
       
    29 #include <string.h>
       
    30 
       
    31 #include "sun_java2d_SunGraphics2D.h"
       
    32 
       
    33 #include "jlong.h"
       
    34 #include "jni_util.h"
       
    35 #import "MTLContext.h"
       
    36 #include "MTLRenderQueue.h"
       
    37 #include "MTLSurfaceDataBase.h"
       
    38 #include "GraphicsPrimitiveMgr.h"
       
    39 #include "Region.h"
       
    40 #include "common.h"
       
    41 
       
    42 #include "jvm.h"
       
    43 
       
    44 extern jboolean MTLSD_InitMTLWindow(JNIEnv *env, MTLSDOps *mtlsdo);
       
    45 extern MTLContext *MTLSD_MakeMTLContextCurrent(JNIEnv *env,
       
    46                                                MTLSDOps *srcOps,
       
    47                                                MTLSDOps *dstOps);
       
    48 
       
    49 #define RGBA_TO_V4(c)              \
       
    50 {                                  \
       
    51     (((c) >> 16) & (0xFF))/255.0f, \
       
    52     (((c) >> 8) & 0xFF)/255.0f,    \
       
    53     ((c) & 0xFF)/255.0f,           \
       
    54     (((c) >> 24) & 0xFF)/255.0f    \
       
    55 }
       
    56 
       
    57 /**
       
    58  * This table contains the standard blending rules (or Porter-Duff compositing
       
    59  * factors) used in glBlendFunc(), indexed by the rule constants from the
       
    60  * AlphaComposite class.
       
    61  */
       
    62 MTLBlendRule MTStdBlendRules[] = {
       
    63 };
       
    64 
       
    65 static struct TxtVertex verts[PGRAM_VERTEX_COUNT] = {
       
    66         {{-1.0, 1.0, 0.0}, {0.0, 0.0}},
       
    67         {{1.0, 1.0, 0.0}, {1.0, 0.0}},
       
    68         {{1.0, -1.0, 0.0}, {1.0, 1.0}},
       
    69         {{1.0, -1.0, 0.0}, {1.0, 1.0}},
       
    70         {{-1.0, -1.0, 0.0}, {0.0, 1.0}},
       
    71         {{-1.0, 1.0, 0.0}, {0.0, 0.0}}
       
    72 };
       
    73 
       
    74 
       
    75 static void _traceMatrix(simd_float4x4 * mtx) {
       
    76     for (int row = 0; row < 4; ++row) {
       
    77         J2dTraceLn4(J2D_TRACE_VERBOSE, "  [%lf %lf %lf %lf]",
       
    78                     mtx->columns[0][row], mtx->columns[1][row], mtx->columns[2][row], mtx->columns[3][row]);
       
    79     }
       
    80 }
       
    81 
       
    82 MTLRenderPassDescriptor* createRenderPassDesc(id<MTLTexture> dest) {
       
    83     MTLRenderPassDescriptor * result = [MTLRenderPassDescriptor renderPassDescriptor];
       
    84     if (result == nil)
       
    85         return nil;
       
    86 
       
    87     if (dest == nil) {
       
    88         J2dTraceLn(J2D_TRACE_ERROR, "_createRenderPassDesc: destination texture is null");
       
    89         return nil;
       
    90     }
       
    91 
       
    92     MTLRenderPassColorAttachmentDescriptor * ca = result.colorAttachments[0];
       
    93     ca.texture = dest;
       
    94     ca.loadAction = MTLLoadActionLoad;
       
    95     ca.clearColor = MTLClearColorMake(0.0f, 0.9f, 0.0f, 1.0f);
       
    96     ca.storeAction = MTLStoreActionStore;
       
    97     return result;
       
    98 }
       
    99 
       
   100 @implementation MTLContext {
       
   101     id<MTLCommandBuffer> _commandBuffer;
       
   102 }
       
   103 
       
   104 @synthesize compState, extraAlpha, alphaCompositeRule, xorPixel, pixel, p0,
       
   105             p1, p3, cyclic, pixel1, pixel2, r, g, b, a, paintState, useMask,
       
   106             useTransform, transform4x4, blitTextureID, textureFunction,
       
   107             vertexCacheEnabled, device, library, pipelineState, pipelineStateStorage,
       
   108             commandQueue, vertexBuffer,
       
   109             color, clipRect, useClip, texturePool;
       
   110 
       
   111 
       
   112  - (id<MTLCommandBuffer>) commandBuffer {
       
   113     if (_commandBuffer == nil) {
       
   114         // NOTE: Command queues are thread-safe and allow multiple outstanding command buffers to be encoded simultaneously.
       
   115         _commandBuffer = [[self.commandQueue commandBuffer] retain];// released in [layer blitTexture]
       
   116     }
       
   117     return _commandBuffer;
       
   118 }
       
   119 
       
   120 - (void)releaseCommandBuffer {
       
   121     [_commandBuffer release];
       
   122     _commandBuffer = nil;
       
   123 }
       
   124 
       
   125 + (MTLContext*) setSurfacesEnv:(JNIEnv*)env src:(jlong)pSrc dst:(jlong)pDst {
       
   126     BMTLSDOps *srcOps = (BMTLSDOps *)jlong_to_ptr(pSrc);
       
   127     BMTLSDOps *dstOps = (BMTLSDOps *)jlong_to_ptr(pDst);
       
   128     MTLContext *mtlc = NULL;
       
   129 
       
   130     if (srcOps == NULL || dstOps == NULL) {
       
   131         J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_SetSurfaces: ops are null");
       
   132         return NULL;
       
   133     }
       
   134 
       
   135     J2dTraceLn6(J2D_TRACE_VERBOSE, "MTLContext_SetSurfaces: bsrc=%p (tex=%p type=%d), bdst=%p (tex=%p type=%d)", srcOps, srcOps->pTexture, srcOps->drawableType, dstOps, dstOps->pTexture, dstOps->drawableType);
       
   136 
       
   137     if (dstOps->drawableType == MTLSD_TEXTURE) {
       
   138         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   139                       "MTLContext_SetSurfaces: texture cannot be used as destination");
       
   140         return NULL;
       
   141     }
       
   142 
       
   143     if (dstOps->drawableType == MTLSD_UNDEFINED) {
       
   144         // initialize the surface as an OGLSD_WINDOW
       
   145         if (!MTLSD_InitMTLWindow(env, dstOps)) {
       
   146             J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   147                           "MTLContext_SetSurfaces: could not init OGL window");
       
   148             return NULL;
       
   149         }
       
   150     }
       
   151 
       
   152     // make the context current
       
   153     MTLSDOps *dstCGLOps = (MTLSDOps *)dstOps->privOps;
       
   154     mtlc = dstCGLOps->configInfo->context;
       
   155 
       
   156     if (mtlc == NULL) {
       
   157         J2dRlsTraceLn(J2D_TRACE_ERROR,
       
   158                       "MTLContext_SetSurfaces: could not make context current");
       
   159         return NULL;
       
   160     }
       
   161 
       
   162     // perform additional one-time initialization, if necessary
       
   163     if (dstOps->needsInit) {
       
   164         if (dstOps->isOpaque) {
       
   165             // in this case we are treating the destination as opaque, but
       
   166             // to do so, first we need to ensure that the alpha channel
       
   167             // is filled with fully opaque values (see 6319663)
       
   168             //MTLContext_InitAlphaChannel();
       
   169         }
       
   170         dstOps->needsInit = JNI_FALSE;
       
   171     }
       
   172 
       
   173     return mtlc;
       
   174 }
       
   175 
       
   176 - (id)initWithDevice:(id<MTLDevice>)d shadersLib:(NSString*)shadersLib {
       
   177     self = [super init];
       
   178     if (self) {
       
   179         // Initialization code here.
       
   180         device = d;
       
   181 
       
   182         texturePool = [[MTLTexturePool alloc] initWithDevice:device];
       
   183         pipelineStateStorage = [[MTLPipelineStatesStorage alloc] initWithDevice:device shaderLibPath:shadersLib];
       
   184 
       
   185         vertexBuffer = [device newBufferWithBytes:verts
       
   186                                            length:sizeof(verts)
       
   187                                           options:MTLResourceCPUCacheModeDefaultCache];
       
   188 
       
   189         NSError *error = nil;
       
   190 
       
   191         library = [device newLibraryWithFile:shadersLib error:&error];
       
   192         if (!library) {
       
   193             NSLog(@"Failed to load library. error %@", error);
       
   194             exit(0);
       
   195         }
       
   196 
       
   197         _commandBuffer = nil;
       
   198 
       
   199         // Create command queue
       
   200         commandQueue = [device newCommandQueue];
       
   201     }
       
   202     return self;
       
   203 }
       
   204 
       
   205 - (void)resetClip {
       
   206     //TODO
       
   207     J2dTraceLn(J2D_TRACE_INFO, "MTLContext.resetClip");
       
   208     useClip = JNI_FALSE;
       
   209 }
       
   210 
       
   211 - (void)setClipRectX1:(jint)x1 Y1:(jint)y1 X2:(jint)x2 Y2:(jint)y2 {
       
   212     //TODO
       
   213     jint width = x2 - x1;
       
   214     jint height = y2 - y1;
       
   215 
       
   216     J2dTraceLn4(J2D_TRACE_INFO, "MTLContext.setClipRect: x=%d y=%d w=%d h=%d", x1, y1, width, height);
       
   217 
       
   218     clipRect.x = x1;
       
   219     clipRect.y = y1;
       
   220     clipRect.width = width;
       
   221     clipRect.height = height;
       
   222     useClip = JNI_TRUE;
       
   223 }
       
   224 
       
   225 - (void)beginShapeClip {
       
   226     //TODO
       
   227     J2dTraceLn(J2D_TRACE_INFO, "MTLContext.beginShapeClip");
       
   228 }
       
   229 
       
   230 - (void)endShapeClip {
       
   231     //TODO
       
   232     J2dTraceLn(J2D_TRACE_INFO, "MTLContext.endShapeClip");
       
   233 }
       
   234 
       
   235 - (void)resetComposite {
       
   236     //TODO
       
   237     J2dTraceLn(J2D_TRACE_INFO, "MTLContext_ResetComposite");
       
   238 }
       
   239 
       
   240 - (void)setAlphaCompositeRule:(jint)rule extraAlpha:(jfloat)_extraAlpha
       
   241                         flags:(jint)flags {
       
   242     J2dTraceLn3(J2D_TRACE_INFO, "MTLContext_SetAlphaComposite: rule=%d, extraAlpha=%1.2f, flags=%d", rule, extraAlpha, flags);
       
   243 
       
   244     extraAlpha = _extraAlpha;
       
   245     alphaCompositeRule = rule;
       
   246 }
       
   247 
       
   248 
       
   249 - (void)setXorComposite:(jint)xp {
       
   250     //TODO
       
   251     J2dTraceLn1(J2D_TRACE_INFO,
       
   252                 "MTLContext.setXorComposite: xorPixel=%08x", xp);
       
   253 }
       
   254 
       
   255 - (jboolean)isBlendingDisabled {
       
   256     // TODO: hold case mtlc->alphaCompositeRule == RULE_SrcOver && sun_java2d_pipe_BufferedContext_SRC_IS_OPAQUE
       
   257     return alphaCompositeRule == RULE_Src && (extraAlpha - 1.0f < 0.001f);
       
   258 }
       
   259 
       
   260 
       
   261 - (void)resetTransform {
       
   262     J2dTraceLn(J2D_TRACE_INFO, "MTLContext_ResetTransform");
       
   263     useTransform = JNI_FALSE;
       
   264 }
       
   265 
       
   266 - (void)setTransformM00:(jdouble) m00 M10:(jdouble) m10
       
   267                     M01:(jdouble) m01 M11:(jdouble) m11
       
   268                     M02:(jdouble) m02 M12:(jdouble) m12 {
       
   269 
       
   270 
       
   271     J2dTraceLn(J2D_TRACE_INFO, "MTLContext_SetTransform");
       
   272 
       
   273     memset(&(transform4x4), 0, sizeof(transform4x4));
       
   274     transform4x4.columns[0][0] = m00;
       
   275     transform4x4.columns[0][1] = m10;
       
   276     transform4x4.columns[1][0] = m01;
       
   277     transform4x4.columns[1][1] = m11;
       
   278     transform4x4.columns[3][0] = m02;
       
   279     transform4x4.columns[3][1] = m12;
       
   280     transform4x4.columns[3][3] = 1.0;
       
   281     transform4x4.columns[4][4] = 1.0;
       
   282     useTransform = JNI_TRUE;
       
   283 }
       
   284 
       
   285 - (jboolean)initBlitTileTexture {
       
   286     //TODO
       
   287     J2dTraceLn(J2D_TRACE_INFO, "MTLContext_InitBlitTileTexture");
       
   288 
       
   289     return JNI_TRUE;
       
   290 }
       
   291 
       
   292 - (jint)createBlitTextureFormat:(jint)internalFormat pixelFormat:(jint)pixelFormat
       
   293                           width:(jint)width height:(jint)height {
       
   294     //TODO
       
   295     return 0;
       
   296 }
       
   297 
       
   298 
       
   299 - (void)setColorR:(int)_r G:(int)_g B:(int)_b A:(int)_a {
       
   300     color = 0;
       
   301     color |= (_r & (0xFF)) << 16;
       
   302     color |= (_g & (0xFF)) << 8;
       
   303     color |= _b & (0xFF);
       
   304     color |= (_a & (0xFF)) << 24;
       
   305     J2dTraceLn4(J2D_TRACE_INFO, "MTLContext.setColor (%d, %d, %d) %d", r,g,b,a);
       
   306 }
       
   307 
       
   308 - (void)setColorInt:(int)_pixel {
       
   309     color = _pixel;
       
   310     J2dTraceLn5(J2D_TRACE_INFO, "MTLContext.setColorInt: pixel=%08x [r=%d g=%d b=%d a=%d]", pixel, (pixel >> 16) & (0xFF), (pixel >> 8) & 0xFF, (pixel) & 0xFF, (pixel >> 24) & 0xFF);
       
   311 }
       
   312 
       
   313 - (id<MTLRenderCommandEncoder>) createEncoderForDest:(id<MTLTexture>) dest {
       
   314     id<MTLCommandBuffer> cb = self.commandBuffer;
       
   315     if (cb == nil)
       
   316         return nil;
       
   317 
       
   318     MTLRenderPassDescriptor * rpd = createRenderPassDesc(dest);
       
   319     if (rpd == nil)
       
   320         return nil;
       
   321 
       
   322     // J2dTraceLn1(J2D_TRACE_VERBOSE, "MTLContext: created render encoder to draw on tex=%p", dest);
       
   323     return [cb renderCommandEncoderWithDescriptor:rpd];
       
   324 }
       
   325 
       
   326 - (void) setEncoderTransform:(id<MTLRenderCommandEncoder>) encoder dest:(id<MTLTexture>) dest {
       
   327     simd_float4x4 normalize;
       
   328     memset(&normalize, 0, sizeof(normalize));
       
   329     normalize.columns[0][0] = 2/(double)dest.width;
       
   330     normalize.columns[1][1] = -2/(double)dest.height;
       
   331     normalize.columns[3][0] = -1.f;
       
   332     normalize.columns[3][1] = 1.f;
       
   333     normalize.columns[3][3] = 1.0;
       
   334     normalize.columns[4][4] = 1.0;
       
   335 
       
   336     if (useTransform) {
       
   337         simd_float4x4 vertexMatrix = simd_mul(normalize, transform4x4);
       
   338         [encoder setVertexBytes:&(vertexMatrix) length:sizeof(vertexMatrix) atIndex:MatrixBuffer];
       
   339     } else {
       
   340         [encoder setVertexBytes:&(normalize) length:sizeof(normalize) atIndex:MatrixBuffer];
       
   341     }
       
   342 }
       
   343 
       
   344 - (id<MTLRenderCommandEncoder>) createRenderEncoderForDest:(id<MTLTexture>) dest {
       
   345     id <MTLRenderCommandEncoder> mtlEncoder = [self createEncoderForDest: dest];
       
   346     if (useClip)
       
   347         [mtlEncoder setScissorRect:clipRect];
       
   348 
       
   349     if (compState == sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR) {
       
   350         // set pipeline state
       
   351         [mtlEncoder setRenderPipelineState:[self.pipelineStateStorage getRenderPipelineState:NO]];
       
   352         struct FrameUniforms uf = {RGBA_TO_V4(color)};
       
   353         [mtlEncoder setVertexBytes:&uf length:sizeof(uf) atIndex:FrameUniformBuffer];
       
   354     } else if (compState == sun_java2d_SunGraphics2D_PAINT_GRADIENT) {
       
   355         // set viewport and pipeline state
       
   356         //[mtlEncoder setRenderPipelineState:gradPipelineState];
       
   357         [mtlEncoder setRenderPipelineState:[self.pipelineStateStorage getRenderPipelineState:YES]];
       
   358 
       
   359         struct GradFrameUniforms uf = {
       
   360                 {p0, p1, p3},
       
   361                 RGBA_TO_V4(pixel1),
       
   362                 RGBA_TO_V4(pixel2)};
       
   363 
       
   364         [mtlEncoder setFragmentBytes: &uf length:sizeof(uf) atIndex:0];
       
   365     }
       
   366     [self setEncoderTransform:mtlEncoder dest:dest];
       
   367     return mtlEncoder;
       
   368 }
       
   369 
       
   370 - (id<MTLRenderCommandEncoder>)createSamplingEncoderForDest:(id<MTLTexture>)dest {
       
   371     id <MTLRenderCommandEncoder> mtlEncoder = [self createRenderEncoderForDest:dest];
       
   372     [mtlEncoder setRenderPipelineState:[pipelineStateStorage getTexturePipelineState:NO compositeRule:alphaCompositeRule]];
       
   373     [self setEncoderTransform:mtlEncoder dest:dest];
       
   374     return mtlEncoder;
       
   375 }
       
   376 
       
   377 - (id<MTLBlitCommandEncoder>)createBlitEncoder {
       
   378     return _commandBuffer == nil ? nil : [_commandBuffer blitCommandEncoder];
       
   379 }
       
   380 
       
   381 - (void)dealloc {
       
   382     J2dTraceLn(J2D_TRACE_INFO, "MTLContext.dealloc");
       
   383 
       
   384     self.texturePool = nil;
       
   385     self.library = nil;
       
   386     self.vertexBuffer = nil;
       
   387     self.commandQueue = nil;
       
   388     self.pipelineState = nil;
       
   389     self.pipelineStateStorage = nil;
       
   390     [super dealloc];
       
   391 }
       
   392 
       
   393 - (void)setGradientPaintUseMask:(jboolean)_useMask cyclic:(jboolean)_cyclic p0:(jdouble) _p0 p1:(jdouble)_p1
       
   394                              p3:(jdouble)_p3 pixel1:(jint)_pixel1 pixel2:(jint)_pixel2 {
       
   395 
       
   396     //TODO Resolve gradient distribution problem
       
   397     //TODO Implement useMask
       
   398     //TODO Implement cyclic
       
   399     //fprintf(stderr,
       
   400     //        "MTLPaints_SetGradientPaint useMask=%d cyclic=%d "
       
   401     //        "p0=%f p1=%f p3=%f pix1=%d pix2=%d\n", useMask, cyclic,
       
   402     //        p0, p1, p3, pixel1, pixel2);
       
   403 
       
   404     compState = sun_java2d_SunGraphics2D_PAINT_GRADIENT;
       
   405     useMask = _useMask;
       
   406     pixel1 = _pixel1;
       
   407     pixel2 = _pixel2;
       
   408     p0 = _p0;
       
   409     p1 = _p1;
       
   410     p3 = _p3;
       
   411     cyclic = _cyclic;
       
   412  }
       
   413 
       
   414 @end
       
   415 
       
   416 /*
       
   417  * Class:     sun_java2d_metal_MTLContext
       
   418  * Method:    getMTLIdString
       
   419  * Signature: ()Ljava/lang/String;
       
   420  */
       
   421 JNIEXPORT jstring JNICALL Java_sun_java2d_metal_MTLContext_getMTLIdString
       
   422   (JNIEnv *env, jclass mtlcc)
       
   423 {
       
   424     char *vendor, *renderer, *version;
       
   425     char *pAdapterId;
       
   426     jobject ret = NULL;
       
   427     int len;
       
   428 
       
   429     return NULL;
       
   430 }
       
   431 
       
   432 
       
   433 
       
   434 #endif /* !HEADLESS */