From 0039c18e0803965e2b90250b20ef952b19826906 Mon Sep 17 00:00:00 2001 From: Jayathirth D V Date: Mon, 5 Apr 2021 05:28:21 +0000 Subject: [PATCH] 8264475: CopyArea ignores clip state in metal rendering pipeline 8251036: SwingSet2 - Dragging internal frame inside jframe leaves artifacts with MetalLookAndFeel Reviewed-by: aghaisas, psadhukhan --- .../libawt_lwawt/java2d/metal/MTLBlitLoops.m | 48 ++++++++++++++----- .../libawt_lwawt/java2d/metal/MTLTexurePool.m | 2 + 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m index 97444da4c6b..58aef56095d 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLBlitLoops.m @@ -800,23 +800,45 @@ MTLBlitLoops_CopyArea(JNIEnv *env, (dstBounds.x1 < dstBounds.x2 && dstBounds.y1 < dstBounds.y2)) { @autoreleasepool { - id cb = [mtlc createCommandBuffer]; - id blitEncoder = [cb blitCommandEncoder]; + struct TxtVertex quadTxVerticesBuffer[6]; + MTLPooledTextureHandle * interHandle = + [mtlc.texturePool getTexture:texWidth + height:texHeight + format:MTLPixelFormatBGRA8Unorm]; + if (interHandle == nil) { + J2dTraceLn(J2D_TRACE_ERROR, + "MTLBlitLoops_CopyArea: texture handle is null"); + return; + } + [[mtlc getCommandBufferWrapper] registerPooledTexture:interHandle]; - // Create an intrermediate buffer - int totalBuffsize = srcWidth * srcHeight * 4; - id buff = [[mtlc.device newBufferWithLength:totalBuffsize options:MTLResourceStorageModePrivate] autorelease]; + id interTexture = interHandle.texture; - [blitEncoder copyFromTexture:dstOps->pTexture - sourceSlice:0 sourceLevel:0 sourceOrigin:MTLOriginMake(srcBounds.x1, srcBounds.y1, 0) sourceSize:MTLSizeMake(srcWidth, srcHeight, 1) - toBuffer:buff destinationOffset:0 destinationBytesPerRow:(srcWidth * 4) destinationBytesPerImage:totalBuffsize]; + /* + * We need to consider common states like clipping while + * performing copyArea, thats why we use drawTex2Tex and + * get encoder with appropriate state from EncoderManager + * and not directly use MTLBlitCommandEncoder for texture copy. + */ - [blitEncoder copyFromBuffer:buff - sourceOffset:0 sourceBytesPerRow:srcWidth*4 sourceBytesPerImage:totalBuffsize sourceSize:MTLSizeMake(srcWidth, srcHeight, 1) - toTexture:dstOps->pTexture destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(dstBounds.x1, dstBounds.y1, 0)]; - [blitEncoder endEncoding]; + // copy content to intermediate texture + drawTex2Tex(mtlc, dstOps->pTexture, interTexture, dstOps->isOpaque, + JNI_FALSE, INTERPOLATION_NEAREST_NEIGHBOR, + 0, 0, texWidth, texHeight, 0, 0, texWidth, texHeight); - [cb commit]; + // copy content with appropriate bounds to destination texture + drawTex2Tex(mtlc, interTexture, dstOps->pTexture, JNI_FALSE, + dstOps->isOpaque, INTERPOLATION_NEAREST_NEIGHBOR, + srcBounds.x1, srcBounds.y1, srcBounds.x2, srcBounds.y2, + dstBounds.x1, dstBounds.y1, dstBounds.x2, dstBounds.y2); + [mtlc.encoderManager endEncoder]; + MTLCommandBufferWrapper * cbwrapper = + [mtlc pullCommandBufferWrapper]; + id commandbuf = [cbwrapper getCommandBuffer]; + [commandbuf addCompletedHandler:^(id commandbuf) { + [cbwrapper release]; + }]; + [commandbuf commit]; } } } diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexurePool.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexurePool.m index 5071afe5657..5c64201a87f 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexurePool.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTexurePool.m @@ -202,6 +202,8 @@ width:(NSUInteger) width height:(NSUInteger) height mipmapped:NO]; + textureDescriptor.usage = MTLTextureUsageRenderTarget | + MTLTextureUsageShaderRead; if (isMultiSample) { textureDescriptor.textureType = MTLTextureType2DMultisample; textureDescriptor.sampleCount = MTLAASampleCount;