【问题标题】:CAMetalLayer with texture rendered by CARenderer is not visible?CARenderer 渲染纹理的 CAMetalLayer 不可见?
【发布时间】:2021-01-31 19:53:33
【问题描述】:

我正在使用CARenderer 将另一个CALayer 树渲染成CAMetalLayer,我希望将其用作另一层的mask。出于测试目的,我尝试将CAMetalLayer 添加为普通子图层而不是蒙版。

下面的layer 对象在添加到绝对可见的超层后不可见。我已经确认该层的frame 没有问题。以下是我制作CAMetalLayer 及其CARenderer 的方法。

CAMetalLayer *layer = [CAMetalLayer layer];
layer.frame = bounds;
layer.device = MTLCreateSystemDefaultDevice();
//layer.opaque = NO;
//layer.framebufferOnly = NO;

id<CAMetalDrawable> drawable = layer.nextDrawable;
_lastDrawable = drawable;

_renderer = [CARenderer rendererWithMTLTexture:drawable.texture options:nil];
_renderer.layer = self.superview.layer;
_renderer.bounds = bounds;

????通过创建CIImage 并使用调试器检查它,我确认CARenderer 正在更新金属纹理。

CIImage *img = [CIImage imageWithMTLTexture:_lastDrawable.texture options:nil];

但是当我设置CAMetalLayersuperlayer 时,它无处可见。

[self.layer addSublayer:layer];

这是我使用CARenderer的方式:

[_renderer beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL];
[_renderer addUpdateRect:bounds];
[_renderer render];
[_renderer endFrame];    

最后一个 sn-p 经常运行。


编辑 1

我添加了一个backgroundColor,现在layer 是可见的,但它的纹理没有在其中渲染。

layer.backgroundColor = NSColor.yellowColor.CGColor;

【问题讨论】:

  • 您使用金属层而不是将层树本身设置为蒙版是否有原因?如果您在进行自定义金属绘图会更有意义,但是在 CA 之外进行往返似乎很奇怪。
  • @NoahWitherspoon 据我了解,CALayer 对象不会在 CPU 上生成位图,所以我想我可以通过使用 GPU 纹理进行屏蔽来减少 CPU 使用率(如果这可能的话) .
  • 我明白了。这是可能的,但我肯定会先尝试更简单的方法。在下面的答案中进行了详细说明。

标签: objective-c macos core-animation calayer metal


【解决方案1】:

我建议将原始图层设置为蒙版,而不是先尝试将其渲染为纹理;你在某种程度上复制了 CA 无论如何都会做的工作。

如果您真的需要控制遮罩层树何时被渲染——同样你应该首先尝试标准方法——正确的方法是创建一个IOSurface-backed MTLTexture,而不是使用CAMetalLayer 的可绘制对象,使用您的 CARenderer 绘制到纹理中,将 IOSurface 设置为常规 CALayer 的内容,并将该图层用作蒙版。

【讨论】:

  • 我确实先尝试了标准的方法,但没有奏效,大概是因为该层已经有一个超级层。换句话说,该图层必须正常渲染,并且还必须是另一个图层的蒙版。我之前问过这个问题:stackoverflow.com/questions/65962728/…
  • 啊,这更有意义。然后我会尝试 IOSurface 路线。
猜你喜欢
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-09
  • 2018-09-16
  • 1970-01-01
相关资源
最近更新 更多