diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/shaders.metal b/src/java.desktop/macosx/native/libawt_lwawt/awt/shaders.metal index 4857aeb33ba..709b1825599 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/shaders.metal +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/shaders.metal @@ -251,6 +251,16 @@ fragment half4 frag_txt( pixelColor.b, srcA)*uniforms.extraAlpha; } +fragment half4 frag_text( + TxtShaderInOut vert [[stage_in]], + texture2d renderTexture [[texture(0)]], + constant TxtFrameUniforms& uniforms [[buffer(1)]], + sampler textureSampler [[sampler(0)]] +) { + float4 pixelColor = renderTexture.sample(textureSampler, vert.texCoords); + return half4(uniforms.color * pixelColor.a); +} + fragment half4 frag_txt_tp(TxtShaderInOut vert [[stage_in]], texture2d renderTexture [[texture(0)]], texture2d paintTexture [[texture(1)]], diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.h index fc89df751ea..0c5efd064e0 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.h @@ -54,6 +54,9 @@ interpolation:(int)interpolation isAA:(jboolean)isAA; +- (id _Nonnull)getTextEncoder:(const BMTLSDOps * _Nonnull)dstOps + isSrcOpaque:(bool)isSrcOpaque; + // Base method to obtain any MTLRenderCommandEncoder - (id _Nonnull) getEncoder:(id _Nonnull)dest isDestOpaque:(jboolean)isDestOpaque diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m index 1597953fc59..3631cc654aa 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/EncoderManager.m @@ -18,13 +18,15 @@ - (void)dealloc; - (void)reset:(id)destination isDstOpaque:(jboolean)isDstOpaque isDstPremultiplied:(jboolean)isDstPremultiplied - isAA:(jboolean)isAA; + isAA:(jboolean)isAA + isText:(jboolean)isText; - (void)updateEncoder:(id)encoder context:(MTLContext *)mtlc renderOptions:(const RenderOptions *)renderOptions forceUpdate:(jboolean)forceUpdate; @property (assign) jboolean aa; +@property (assign) jboolean text; @property (retain) MTLPaint* paint; @end @@ -37,6 +39,7 @@ @implementation EncoderStates { SurfaceRasterFlags _dstFlags; jboolean _isAA; + jboolean _isText; // // Cached 'mutable' states of encoder @@ -60,6 +63,7 @@ @implementation EncoderStates { MTLTransform * _transform; } @synthesize aa = _isAA; +@synthesize text = _isText; @synthesize paint = _paint; - (id)init { @@ -89,11 +93,13 @@ - (void)setContext:(MTLContext * _Nonnull)mtlc { - (void)reset:(id)destination isDstOpaque:(jboolean)isDstOpaque isDstPremultiplied:(jboolean)isDstPremultiplied - isAA:(jboolean)isAA { + isAA:(jboolean)isAA + isText:(jboolean)isText { _destination = destination; _dstFlags.isOpaque = isDstOpaque; _dstFlags.isPremultiplied = isDstPremultiplied; _isAA = isAA; + _isText = isText; // NOTE: probably it's better to invalidate/reset all cached states now } @@ -141,6 +147,7 @@ - (void)updatePipelineState:(id)encoder && [_composite isEqual:mtlc.composite] && (_isTexture == renderOptions->isTexture && (!renderOptions->isTexture || _interpolationMode == renderOptions->interpolation)) // interpolation is used only in texture mode && _isAA == renderOptions->isAA + && _isText == renderOptions->isText && _srcFlags.isOpaque == renderOptions->srcFlags.isOpaque && _srcFlags.isPremultiplied == renderOptions->srcFlags.isPremultiplied) return; @@ -149,6 +156,7 @@ - (void)updatePipelineState:(id)encoder _isTexture = renderOptions->isTexture; _interpolationMode = renderOptions->interpolation; _isAA = renderOptions->isAA; + _isText = renderOptions->isText; _srcFlags = renderOptions->srcFlags; if ((jint)[mtlc.composite getCompositeState] == sun_java2d_SunGraphics2D_COMP_XOR) { @@ -242,14 +250,14 @@ - (void)setContext:(MTLContex * _Nonnull)mtlc { - (id _Nonnull)getAARenderEncoder:(const BMTLSDOps * _Nonnull)dstOps { id dstTxt = dstOps->pTexture; - RenderOptions roptions = {JNI_FALSE, JNI_TRUE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {dstOps->isOpaque, JNI_TRUE}}; + RenderOptions roptions = {JNI_FALSE, JNI_TRUE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {dstOps->isOpaque, JNI_TRUE}, JNI_FALSE}; return [self getEncoder:dstTxt renderOptions:&roptions]; } - (id _Nonnull)getRenderEncoder:(id _Nonnull)dest isDstOpaque:(bool)isOpaque { - RenderOptions roptions = {JNI_FALSE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {isOpaque, JNI_TRUE}}; + RenderOptions roptions = {JNI_FALSE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, defaultRasterFlags, {isOpaque, JNI_TRUE}, JNI_FALSE}; return [self getEncoder:dest renderOptions:&roptions]; } @@ -279,7 +287,7 @@ - (void)setContext:(MTLContex * _Nonnull)mtlc { interpolation:(int)interpolation isAA:(jboolean)isAA { - RenderOptions roptions = {JNI_TRUE, isAA, interpolation, { isSrcOpaque, JNI_TRUE }, {isDstOpaque, JNI_TRUE}}; + RenderOptions roptions = {JNI_TRUE, isAA, interpolation, { isSrcOpaque, JNI_TRUE }, {isDstOpaque, JNI_TRUE}, JNI_FALSE}; return [self getEncoder:dest renderOptions:&roptions]; } @@ -291,6 +299,13 @@ - (void)setContext:(MTLContex * _Nonnull)mtlc { return [self getTextureEncoder:dest isSrcOpaque:isSrcOpaque isDstOpaque:isDstOpaque interpolation:interpolation isAA:JNI_FALSE]; } +- (id _Nonnull) getTextEncoder:(const BMTLSDOps * _Nonnull)dstOps + isSrcOpaque:(bool)isSrcOpaque +{ + RenderOptions roptions = {JNI_TRUE, JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, { isSrcOpaque, JNI_TRUE }, {dstOps->isOpaque, JNI_TRUE}, JNI_TRUE}; + return [self getEncoder:dstOps->pTexture renderOptions:&roptions]; +} + - (id _Nonnull) getEncoder:(id _Nonnull)dest renderOptions:(const RenderOptions * _Nonnull)renderOptions { @@ -358,7 +373,8 @@ - (void)setContext:(MTLContex * _Nonnull)mtlc { [_encoderStates reset:dest isDstOpaque:renderOptions->dstFlags.isOpaque isDstPremultiplied:YES - isAA:renderOptions->isAA]; + isAA:renderOptions->isAA + isText:renderOptions->isText]; } // diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m index e10c4dc3964..c063efc0431 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPaints.m @@ -161,6 +161,9 @@ - (void)setPipelineState:(id)encoder fragShader = @"aa_frag_txt"; rpDesc = [[templateAATexturePipelineDesc copy] autorelease]; } + if (renderOptions->isText) { + fragShader = @"frag_text"; + } setTxtUniforms(encoder, _color, 1, renderOptions->interpolation, NO, [mtlc.composite getExtraAlpha], &renderOptions->srcFlags, &renderOptions->dstFlags); diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m index 592709a3f4d..87e5624c8ea 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m @@ -59,7 +59,7 @@ - (NSPointerArray * ) getSubStates:(NSString *)vertexShaderId fragmentShader:(NS vertexShaderId:(NSString *)vertexShaderId fragmentShaderId:(NSString *)fragmentShaderId { - RenderOptions defaultOptions = {JNI_FALSE, JNI_FALSE, 0/*unused*/, {JNI_FALSE, JNI_TRUE}, {JNI_FALSE, JNI_TRUE}}; + RenderOptions defaultOptions = {JNI_FALSE, JNI_FALSE, 0/*unused*/, {JNI_FALSE, JNI_TRUE}, {JNI_FALSE, JNI_TRUE}, JNI_FALSE}; return [self getPipelineState:pipelineDescriptor vertexShaderId:vertexShaderId fragmentShaderId:fragmentShaderId diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m index 1e11407b6ca..5d91f0cc574 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m @@ -132,7 +132,8 @@ { J2dTraceLn(J2D_TRACE_INFO, "MTLTR_InitGlyphCache"); // TODO : Need to fix RGB order in case of LCD - MTLPixelFormat pixelFormat = MTLPixelFormatBGRA8Unorm; + MTLPixelFormat pixelFormat = + lcdCache ? MTLPixelFormatBGRA8Unorm : MTLPixelFormatA8Unorm; MTLGlyphCacheInfo *gcinfo; // init glyph cache data structure @@ -220,30 +221,10 @@ {w, h, 1} }; if (!lcdCache) { - // Opengl uses GL_INTENSITY as internal pixel format to set number of - // color components in the texture for grayscale texture. - // It is mentioned that for GL_INTENSITY format, - // the GL assembles it into an RGBA element by replicating the - // intensity value three times for red, green, blue, and alpha. - // To let metal behave the same for grayscale text, - // we need to make sure we create BGRA component by replicating - // graycale pixel value as in R=G=B=A=grayscale pixel value - - unsigned int imageBytes = w * h * 4; - unsigned char imageData[imageBytes]; - memset(&imageData, 0, sizeof(imageData)); - - unsigned int dstindex = 0; - for (int i = 0; i < (w * h); i++) { - imageData[dstindex++] = glyph->image[i]; - imageData[dstindex++] = glyph->image[i]; - imageData[dstindex++] = glyph->image[i]; - imageData[dstindex++] = glyph->image[i]; - } - NSUInteger bytesPerRow = 4 * w; + NSUInteger bytesPerRow = 1 * w; [gcinfo->texture replaceRegion:region mipmapLevel:0 - withBytes:imageData + withBytes:glyph->image bytesPerRow:bytesPerRow]; } else { unsigned int imageBytes = w * h * 4; diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m index 647f51d52b5..a64ff1dd2b6 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLVertexCache.m @@ -247,7 +247,9 @@ void MTLVertexCache_FreeVertexCache() void MTLVertexCache_CreateSamplingEncoder(MTLContext *mtlc, BMTLSDOps *dstOps) { J2dTraceLn(J2D_TRACE_INFO, "MTLVertexCache_CreateSamplingEncoder"); - encoder = [mtlc.encoderManager getTextureEncoder:dstOps isSrcOpaque:NO]; + //encoder = [mtlc.encoderManager getTextureEncoder:dstOps isSrcOpaque:NO]; + encoder = [mtlc.encoderManager getTextEncoder:dstOps + isSrcOpaque:NO]; } void diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h index 5edcdd8b5e6..772876949d5 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/RenderOptions.h @@ -11,6 +11,7 @@ typedef struct { int interpolation; SurfaceRasterFlags srcFlags; SurfaceRasterFlags dstFlags; + jboolean isText; } RenderOptions;