8250658: Performance of ClipFlatOval Renderperf test is very low
Reviewed-by: jdv, aghaisas
This commit is contained in:
parent
4727187f86
commit
7433821910
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user