The MTLTexture size is not updated when resizing the View

Working on the project using Metal. Instead of using MTKView, I use a customized View inherited from NSView and use CAMetalLayer as backing layer:


- (CALayer*)makeBackingLayer

{

return [CAMetalLayer layer];

}


- (instancetype)initWithFrame:(NSRect)frameRect

{

self = [super initWithFrame:frameRect];


if ( self != nullptr )

{

[self setWantsLayer:YES];

[self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawDuringViewResize];

}


return self;

}


When first showing, the rendering is OK. But after resizing the View, the rendering is weird. After debugging, I find that, after resizing, the bounds of NSView and CAMetalLayer are already updated, but the MTLTexture's size is still the old one:


(lldb) po m_metalLayer # the same address for m_metalLayer between resizing.

<CAMetalLayer:0x610000c2f620; position = CGPoint (0 0); bounds = CGRect (0 0; 1126 636); delegate = <MyMetalView: 0x610000192bd0>; contents = <CAImageQueue 0x610000190a80>; opaque = YES; masksToBounds = YES; allowsDisplayCompositing = YES; contentsScale = 2; backgroundFilters = (

); filters = (

); shadowColor = (null); anchorPoint = CGPoint (0 0); NS_view = <MyMetalView: 0x610000192bd0>>


(lldb) po NSStringFromSize([m_metalLayer drawableSize]) #the drawableSize is not equal to bounds * contentsScale.

{2984, 1604}

(lldb) po [[m_metalLayer nextDrawable] texture]

<BronzeMtlTexture: 0x14a074280>

label = Drawable

textureType = MTLTextureType2D

pixelFormat = MTLPixelFormatBGRA8Unorm

width = 2984

height = 1604

depth = 1

arrayLength = 1

mipmapLevelCount = 1

sampleCount = 1

cpuCacheMode = MTLCPUCacheModeDefaultCache

storageMode = MTLStorageModeManaged

resourceOptions = MTLResourceCPUCacheModeDefaultCache MTLResourceStorageModeManaged

usage = MTLTextureUsageShaderRead MTLTextureUsageShaderWrite MTLTextureUsageRenderTarget MTLTextureUsagePixelFormatView

framebufferOnly = 1

purgeableState = MTLPurgeableStateNonVolatile

parentTexture = <null>

parentRelativeLevel = 0

parentRelativeSlice = 0

buffer = <null>

bufferOffset = 0

bufferBytesPerRow = 0

iosurface = 0x61c000003580

iosurfacePlane = 0

label = Drawable


Did I miss something here?


And For MTKView class, it has autoResizeDrawable property ( https://developer.apple.com/documentation/metalkit/mtkview/1535938-autoresizedrawable?language=objc) How can I achieve the same result for normal NSview with MTKView's autoResizeDrawable = YES?


Thanks.

Accepted Reply

Have you tried resizing your layer manually, with CAMetalLayer's setDrawableSize?

Replies

Have you tried resizing your layer manually, with CAMetalLayer's setDrawableSize?

Yes, it works. It turns out that I need to call setDrawableSize method when the NSView's bounds changed.


Thanks!