8250658: Performance of ClipFlatOval Renderperf test is very low

Reviewed-by: jdv, aghaisas
This commit is contained in:
Alexey Ushakov 2021-05-12 12:33:45 +00:00 committed by Ajit Ghaisas
parent 4727187f86
commit 7433821910
7 changed files with 33 additions and 81 deletions

View File

@ -424,6 +424,12 @@ const SurfaceRasterFlags defaultRasterFlags = { JNI_FALSE, JNI_TRUE };
rpd.stencilAttachment.loadAction = MTLLoadActionLoad;
rpd.stencilAttachment.storeAction = MTLStoreActionStore;
rpd.stencilAttachment.texture = _mtlc.clip.stencilTextureRef;
} else if (_mtlc.clip.stencilMaskGenerationInProgress == YES) {
rpd.stencilAttachment.texture = _mtlc.clip.dstOps->pStencilTexture;
rpd.stencilAttachment.clearStencil = 0;
rpd.stencilAttachment.loadAction = _mtlc.clip.stencilMaskGenerationStarted? MTLLoadActionLoad : MTLLoadActionClear;
_mtlc.clip.stencilMaskGenerationStarted = YES;
rpd.stencilAttachment.storeAction = MTLStoreActionStore;
}
// J2dTraceLn1(J2D_TRACE_VERBOSE, "created render encoder to draw on

View File

@ -49,10 +49,12 @@ enum Clip {
@interface MTLClip : NSObject
@property (readonly) id<MTLTexture> stencilTextureRef;
@property (readonly) BOOL stencilMaskGenerationInProgress;
@property (readwrite ) BOOL stencilMaskGenerationStarted;
@property NSUInteger shapeX;
@property NSUInteger shapeY;
@property NSUInteger shapeWidth;
@property NSUInteger shapeHeight;
@property (readonly) BMTLSDOps* dstOps;
- (id)init;
- (BOOL)isEqual:(MTLClip *)other; // used to compare requested with cached

View File

@ -47,6 +47,7 @@ static void initTemplatePipelineDescriptors() {
templateStencilPipelineDesc.sampleCount = 1;
templateStencilPipelineDesc.vertexDescriptor = vertDesc;
templateStencilPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatR8Uint; // A byte buffer format
templateStencilPipelineDesc.stencilAttachmentPixelFormat = MTLPixelFormatStencil8;
templateStencilPipelineDesc.label = @"template_stencil";
}
@ -56,11 +57,14 @@ static void initTemplatePipelineDescriptors() {
MTLContext* _mtlc;
BMTLSDOps* _dstOps;
BOOL _stencilMaskGenerationInProgress;
BOOL _stencilMaskGenerationStarted;
BOOL _clipReady;
MTLOrigin _clipShapeOrigin;
MTLSize _clipShapeSize;
}
@synthesize dstOps = _dstOps;
- (id)init {
self = [super init];
if (self) {
@ -68,6 +72,7 @@ static void initTemplatePipelineDescriptors() {
_mtlc = nil;
_dstOps = NULL;
_stencilMaskGenerationInProgress = NO;
_stencilMaskGenerationStarted = NO;
_clipReady = NO;
}
return self;
@ -143,7 +148,7 @@ static void initTemplatePipelineDescriptors() {
- (void)beginShapeClip:(BMTLSDOps *)dstOps context:(MTLContext *)mtlc {
_stencilMaskGenerationInProgress = YES;
_mtlc = mtlc;
if ((dstOps == NULL) || (dstOps->pStencilData == NULL) || (dstOps->pStencilTexture == NULL)) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLContext_beginShapeClip: stencil render target or stencil texture is NULL");
return;
@ -158,17 +163,7 @@ static void initTemplatePipelineDescriptors() {
_clipShapeSize = MTLSizeMake(0, 0, 1);
// Use out of bounds origin to correctly calculate shape boundaries
_clipShapeOrigin = MTLOriginMake((NSUInteger) dstOps->width, (NSUInteger) dstOps->height, 0);
MTLRenderPassDescriptor* clearPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
// set color buffer properties
clearPassDescriptor.colorAttachments[0].texture = dstOps->pStencilData;
clearPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
clearPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0f, 0.0f,0.0f, 0.0f);
id<MTLCommandBuffer> commandBuf = [mtlc createCommandBuffer];
id <MTLRenderCommandEncoder> clearEncoder = [commandBuf renderCommandEncoderWithDescriptor:clearPassDescriptor];
[clearEncoder endEncoding];
[commandBuf commit];
_dstOps = dstOps;
}
}
@ -190,28 +185,8 @@ static void initTemplatePipelineDescriptors() {
}];
[commandBuffer commit];
// Now the stencil data is ready, this needs to be used while rendering further
@autoreleasepool {
if (_clipShapeSize.width > 0 && _clipShapeSize.height > 0) {
id<MTLCommandBuffer> cb = [mtlc createCommandBuffer];
id<MTLBlitCommandEncoder> blitEncoder = [cb blitCommandEncoder];
[blitEncoder copyFromTexture:dstOps->pStencilData
sourceSlice:0
sourceLevel:0
sourceOrigin:_clipShapeOrigin
sourceSize:_clipShapeSize
toBuffer:dstOps->pStencilDataBuf
destinationOffset:0
destinationBytesPerRow:_clipShapeSize.width
destinationBytesPerImage:_clipShapeSize.width*_clipShapeSize.height];
[blitEncoder endEncoding];
[cb commit];
}
}
_stencilMaskGenerationInProgress = JNI_FALSE;
_mtlc = mtlc;
_stencilMaskGenerationInProgress = NO;
_stencilMaskGenerationStarted = NO;
_dstOps = dstOps;
_clipType = SHAPE_CLIP;
_clipReady = NO;
@ -227,7 +202,8 @@ static void initTemplatePipelineDescriptors() {
// A PipelineState for rendering to a byte-buffered texture that will be used as a stencil
id <MTLRenderPipelineState> pipelineState = [pipelineStateStorage getPipelineState:templateStencilPipelineDesc
vertexShaderId:@"vert_stencil"
fragmentShaderId:@"frag_stencil"];
fragmentShaderId:@"frag_stencil"
stencilNeeded:YES];
[encoder setRenderPipelineState:pipelineState];
struct FrameUniforms uf; // color is ignored while writing to stencil buffer
@ -239,6 +215,8 @@ static void initTemplatePipelineDescriptors() {
_clipRect.width = dw;
_clipRect.height = dh;
[encoder setDepthStencilState: _mtlc.stencilManager.genStencilState];
[encoder setStencilReferenceValue:255];
[encoder setScissorRect:_clipRect]; // just for insurance (to reset possible clip from previous drawing)
}
@ -301,41 +279,7 @@ static void initTemplatePipelineDescriptors() {
- (id<MTLTexture>) stencilTextureRef {
if (_dstOps == NULL) return nil;
id <MTLTexture> _stencilTextureRef = _dstOps->pStencilTexture;
if (!_clipReady) {
@autoreleasepool {
MTLRenderPassDescriptor* clearPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
// set color buffer properties
clearPassDescriptor.stencilAttachment.texture = _stencilTextureRef;
clearPassDescriptor.stencilAttachment.clearStencil = 0;
clearPassDescriptor.stencilAttachment.loadAction = MTLLoadActionClear;
clearPassDescriptor.stencilAttachment.storeAction = MTLStoreActionStore;
id<MTLCommandBuffer> commandBuf = [_mtlc createCommandBuffer];
id <MTLRenderCommandEncoder> clearEncoder = [commandBuf renderCommandEncoderWithDescriptor:clearPassDescriptor];
[clearEncoder endEncoding];
[commandBuf commit];
id <MTLCommandBuffer> cb = [_mtlc createCommandBuffer];
id <MTLBlitCommandEncoder> blitEncoder = [cb blitCommandEncoder];
id <MTLBuffer> _stencilDataBufRef = _dstOps->pStencilDataBuf;
[blitEncoder copyFromBuffer:_stencilDataBufRef
sourceOffset:0
sourceBytesPerRow:_clipShapeSize.width
sourceBytesPerImage:_clipShapeSize.width * _clipShapeSize.height
sourceSize:_clipShapeSize
toTexture:_stencilTextureRef
destinationSlice:0
destinationLevel:0
destinationOrigin:_clipShapeOrigin];
[blitEncoder endEncoding];
[cb commit];
_clipReady = YES;
}
}
return _stencilTextureRef;
return _dstOps->pStencilTexture;;
}
- (NSUInteger)shapeX {

View File

@ -37,6 +37,7 @@
- (id _Nonnull)initWithDevice:(_Nonnull id<MTLDevice>) device;
- (void)dealloc;
@property (readonly) _Nonnull id<MTLDepthStencilState> stencilState;
@property (readonly) _Nonnull id<MTLDepthStencilState> genStencilState;
@end
#endif // MTLSamplerManager_h_Included

View File

@ -30,9 +30,11 @@
@implementation MTLStencilManager {
id<MTLDepthStencilState> _stencilState;
id<MTLDepthStencilState> _genStencilState;
}
@synthesize stencilState = _stencilState;
@synthesize genStencilState = _genStencilState;
- (id _Nonnull)initWithDevice:(id<MTLDevice>) device {
self = [super init];
@ -50,6 +52,14 @@
stencilDescriptor.backFaceStencil.stencilCompareFunction = MTLCompareFunctionEqual;
stencilDescriptor.backFaceStencil.stencilFailureOperation = MTLStencilOperationKeep;
_stencilState = [device newDepthStencilStateWithDescriptor:stencilDescriptor];
MTLDepthStencilDescriptor* genStencilDescriptor;
genStencilDescriptor = [[MTLDepthStencilDescriptor new] autorelease];
genStencilDescriptor.backFaceStencil.stencilCompareFunction = MTLCompareFunctionAlways;
genStencilDescriptor.backFaceStencil.depthStencilPassOperation = MTLStencilOperationReplace;
genStencilDescriptor.frontFaceStencil.stencilCompareFunction = MTLCompareFunctionAlways;
genStencilDescriptor.frontFaceStencil.depthStencilPassOperation = MTLStencilOperationReplace;
_genStencilState = [device newDepthStencilStateWithDescriptor:genStencilDescriptor];
}
return self;
}

View File

@ -91,17 +91,12 @@ static jboolean MTLSurfaceData_initTexture(BMTLSDOps *bmtlsdo, jboolean isOpaque
stencilDataDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
stencilDataDescriptor.storageMode = MTLStorageModePrivate;
bmtlsdo->pStencilData = [ctx.device newTextureWithDescriptor:stencilDataDescriptor];
bmtlsdo->pAAStencilData = [ctx.device newTextureWithDescriptor:textureDescriptor];
bmtlsdo->pStencilDataBuf = [ctx.device newBufferWithLength:width*height options:MTLResourceStorageModePrivate];
bmtlsdo->pAAStencilDataBuf = [ctx.device newBufferWithLength:width*height*4 options:MTLResourceStorageModePrivate];
MTLTextureDescriptor *stencilTextureDescriptor =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatStencil8 width:width height:height mipmapped:NO];
stencilTextureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite;
stencilTextureDescriptor.storageMode = MTLStorageModePrivate;
bmtlsdo->pStencilTexture = [ctx.device newTextureWithDescriptor:stencilTextureDescriptor];
bmtlsdo->isOpaque = isOpaque;
bmtlsdo->xOffset = 0;
bmtlsdo->yOffset = 0;
@ -196,9 +191,6 @@ MTLSD_Delete(JNIEnv *env, BMTLSDOps *bmtlsdo)
[(NSObject *)bmtlsdo->pTexture release];
[(NSObject *)bmtlsdo->pStencilTexture release];
[(NSObject *)bmtlsdo->pStencilData release];
[(NSObject *)bmtlsdo->pStencilDataBuf release];
[(NSObject *)bmtlsdo->pAAStencilData release];
[(NSObject *)bmtlsdo->pAAStencilDataBuf release];
bmtlsdo->pTexture = NULL;
bmtlsdo->drawableType = MTLSD_UNDEFINED;
}

View File

@ -94,10 +94,7 @@ typedef struct {
jint height;
void* pTexture;
void* pStencilData; // stencil data to be rendered to this buffer
void* pStencilDataBuf; // MTLBuffer with stencil data
void* pStencilTexture; // stencil texture byte buffer stencil mask used in main rendering
void* pAAStencilData; // stencil data for AA rendering
void* pAAStencilDataBuf; // MTLBuffer with AA stencil data
jint textureWidth;
jint textureHeight;
} BMTLSDOps;