【问题标题】:CATiledLayer drawLayer:inContext always being called on Main thread - MacOS El CapitanCATiledLayer drawLayer:inContext 总是在主线程上被调用 - MacOS El Capitan
【发布时间】:2017-01-26 15:27:45
【问题描述】:

我正在使用支持 CATiledLayer 的 NSView(Mac 不是 iOS),根据 Apple 文档 https://developer.apple.com/reference/quartzcore/catiledlayer 我希望这将在多个线程上异步调用以提高性能,但它似乎只在主线程上被调用线程。

我正在drawLayer(layer: CALayer, inContext ctx: CGContext)做这项工作

我在 NSView 上启用了canDrawConcurrently,并确保窗口将allowsConcurrentViewDrawing 设置为 true(默认),但它仍然总是为每个磁贴矩形调用主线程。

我需要在显示之前根据需要显示的矩形区域进行一些图像处理,并且在主线程上运行会影响性能。

有什么办法可以强制它调用后台线程吗?

我尝试将图像编组到后台线程上,然后使用以下内容调用主队列,但它显示一个空白矩形:

backgroundQueue.addOperationWithBlock({ [ weak self ] in            
    guard let strongSelf = self else { return }

    // ** This is the part I nee to do in background that can take some time
    guard let image = strongSelf.imageForTileRect(layerBounds, imageSize: imageSize) else { return }
    // ** End background bit

    var rect = layerBounds
    let rectImageRef = image.CGImageForProposedRect(&rect, context: nil, hints: nil)

    if (rectImageRef != nil) {
        NSOperationQueue.mainQueue().addOperationWithBlock({ 
            CGContextDrawImage(ctx, rect, rectImageRef)
        })
    }
})

【问题讨论】:

  • 你有没有想过这个问题?我看到了同样的事情。我想使用后台线程为我的 NSView 绘制到我的 CATiledLayer。
  • 这里有更多上下文。如果我将另一个 CATiledLayer 作为叠加层添加到作为我的支持叠加层的叠加层,它会在后台呈现。只是作为我视图支持的主线程在主线程上呈现。我最终可能会将主要的设置为空白,并将我的渲染放到叠加层 CATiledLayer。

标签: macos core-animation calayer nsview catiledlayer


【解决方案1】:

当 CATiledLayer 是主要层时,我们从未真正设法让它工作,我不确定它为什么不起作用,而且我们从未从提出的 Apple 错误中得到答案。

但是,我们通过将主层设置为标准 CALayer,然后将 CATiledLayer 作为子层添加到该主层,来实现后台渲染,类似于下面的代码。

我们还注意到,如果将 CATiledLayer 托管在 NSView 中,它会按预期工作

希望这会有所帮助...

class HostingLayer : CALayer {

    var tiledLayer : CATiledLayer!

    override init() {
        super.init()

        self.tiledLayer = CATiledLayer.init()

        self.addSublayer(tiledLayer!)
    }
}

【讨论】:

    【解决方案2】:

    所以这就是我所做的工作,尽管它并不理想。在我的CATiledLayer 支持NSView 的drawRect: 中,我画了一个简单的背景(在我的例子中是一个简单的网格)。我创建了另一个CATiledLayer 并将其添加到我的 NSView 层作为子层,并将 NSView 设置为其委托。第二个 `CATiledLayer' 正在后台线程上获取委托绘制调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多