代码之家  ›  专栏  ›  技术社区  ›  user007

使用NSView进行图层备份绘制时未调用drawRect

  •  0
  • user007  · 技术社区  · 7 年前

    我正在尝试将我的Opengl应用程序迁移到Metal,我正在使用 CAMetalLayer 对于金属实现。 我已在继承的 NSView

    self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize;
    [self setWantsLayer:YES];
    

    我查过其他答案,比如 NSView subclass - drawRect: not called

    所以,我试着按照上面答案中的建议分配代表,类似这样的

    [self.layer setDelegate:self];
    

    我得到以下编译错误:

    Cannot initialize a parameter of type 'id<CALayerDelegate> _Nullable' with an lvalue of type 'MyNSView *'
    

    此外,我还看到了在 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/SettingUpLayerObjects/SettingUpLayerObjects.html ,其中指出:

    替代视图方法以进行绘图。分层视图 自动使自己成为其层的代理并实现 所需的委托方法,您不应该更改它 配置。相反,您应该实现视图drawRect: 方法来绘制内容。

    因此,根据这个,我甚至不必在我的案例中设置委托,我已经在实现 drawRect 中的函数 MyNSView . 还是没人打电话。

    编辑 因此,我修复了编译错误,使我的层遵循协议 CALayerDelegate ,但我还是没有接到任何电话 drawLayer 或 画矩形 .

    - (CALayer*)makeBackingLayer
    {
        id <MTLDevice> device = MTLCreateSystemDefaultDevice();
        CAMetalLayer *backingLayer   = [CAMetalLayer layer];
        backingLayer.opaque          = YES;
        backingLayer.device          = device;
        backingLayer.pixelFormat     = MTLPixelFormatBGRA8Unorm;
        backingLayer.framebufferOnly = YES;
    
    //    [backingLayer setDelegate:self]; //Tried setting the delegate 
                                           //here as well
    
        return backingLayer;
    }
    

    初始化函数

    self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize;
    [self setWantsLayer:YES];
    [self.layer setDelegate:self];
    

    绘图函数

    - (void)displayLayer:(CALayer *)layer
    {
        [self drawRect:self.bounds];
    }
    
    - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
        [self drawRect:self.bounds];
    }
    
    -(void) drawRect: (NSRect) dirtyRect
    {
        [super drawRect:dirtyRect];
    }
    

    我已经实现了所有的draw函数来检查它们是否被命中,但是我没有收到任何一个函数的调用。

    为了将内容绘制到NSView,我将绘制到屏幕外资源,并获取 drawable 从NSView的CALayer打电话过来 presentDrawable 在提交 commandBuffer

    1 回复  |  直到 7 年前
        1
  •  1
  •   user007    7 年前

    因为这里没有太多可以调试的地方,所以我开始按照指令的执行顺序进行调试。事实证明,你打电话的顺序是:

    [self setWantsLayer:YES];
    self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize;
    

    是问题的根源。在交换这两个语句时,我开始接到我的 displayLayer 功能。我还是不明白为什么 drawRect 不需要层备份的NSView。

    张贴这只是为了以防万一,这个交换修复了其他人的问题以及。

    推荐文章