<!--
{
  "availability" : [
    "iOS: 8.0.0 -",
    "iPadOS: 8.0.0 -",
    "macCatalyst: 13.1.0 -",
    "macOS: 10.11.0 -",
    "tvOS: 9.0.0 -",
    "visionOS: 1.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "QuartzCore",
  "identifier" : "/documentation/QuartzCore/CAMetalLayer",
  "metadataVersion" : "0.1.0",
  "role" : "Class",
  "symbol" : {
    "kind" : "Class",
    "modules" : [
      "Core Animation"
    ],
    "preciseIdentifier" : "c:objc(cs)CAMetalLayer"
  },
  "title" : "CAMetalLayer"
}
-->

# CAMetalLayer

A Core Animation layer that Metal can render into, typically displayed onscreen.

```
class CAMetalLayer
```

## Overview

Use a [`CAMetalLayer`](/documentation/QuartzCore/CAMetalLayer) when you want to use Metal to render a layer’s contents; for example, to render into a view. Consider using <doc://com.apple.documentation/documentation/MetalKit/MTKView> instead, because this class automatically wraps a [`CAMetalLayer`](/documentation/QuartzCore/CAMetalLayer) object and provides a higher-level abstraction.

If you’re using UIKit, to create a view that uses a [`CAMetalLayer`](/documentation/QuartzCore/CAMetalLayer), create a subclass of [UIView](https://developer.apple.com/library/archive/releasenotes/iPhone/RN-iPhoneSDK/index.html#//apple_ref/doc/uid/TP40007428-CH1-SW18) and override its <doc://com.apple.documentation/documentation/UIKit/UIView/layerClass> class method to return a [`CAMetalLayer`](/documentation/QuartzCore/CAMetalLayer):

```objc
+ (Class) layerClass
{
    return [CAMetalLayer class];
}
```

If you’re using AppKit, configure an <doc://com.apple.documentation/documentation/AppKit/NSView> object to use a backing layer and assign a [`CAMetalLayer`](/documentation/QuartzCore/CAMetalLayer) object to the view:

```objc
myView.wantsLayer = YES;
myView.layer = [CAMetalLayer layer];
```

Adjust the layer’s properties to configure its underlying pixel format and other display behaviors.

### Rendering the Layer’s Contents

A [`CAMetalLayer`](/documentation/QuartzCore/CAMetalLayer) creates a pool of Metal drawable objects ([`CAMetalDrawable`](/documentation/QuartzCore/CAMetalDrawable)). At any given time, one of these drawable objects contains the contents of the layer. To change the layer’s contents, ask the layer for a drawable object, render into it, and then update the layer’s contents to point to the new drawable.

Call the layer’s [`nextDrawable()`](/documentation/QuartzCore/CAMetalLayer/nextDrawable()) method to obtain a drawable object. Get the drawable object’s texture and create a render pass that renders to that texture, as shown in the code below:

```objc
CAMetalLayer *metalLayer = (CAMetalLayer*)self.layer;
id<CAMetalDrawable> *drawable = [metalLayer nextDrawable];

MTLRenderPassDescriptor *renderPassDescriptor
                               = [MTLRenderPassDescriptor renderPassDescriptor];

renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0,0.0,0.0,1.0);
...
```

To change the layer’s contents to the new drawable, call the <doc://com.apple.documentation/documentation/Metal/MTLCommandBuffer/present(_:)> method (or one of its variants) on the command buffer containing the encoded render pass, passing in the drawable object to present.

```objc
[commandBuffer presentDrawable:drawable];
```

### Keeping References to Drawables

The layer reuses a drawable only if it isn’t onscreen and there are no strong references to it. Further, if a drawable isn’t available when you call [`nextDrawable()`](/documentation/QuartzCore/CAMetalLayer/nextDrawable()), the system waits for one to become available. To avoid stalls in your app, request a new drawable only when you need it, and release any references to it as quickly as possible after you’re done with it.

For example, before retrieving a new drawable, you might perform other work on the CPU or submit commands to the GPU that don’t require the drawable. Then, obtain the drawable and encode a command buffer to render into it, as described above. After you commit this command buffer, release all strong references to the drawable. If you don’t release drawables correctly, the layer runs out of drawables, and future calls to [`nextDrawable()`](/documentation/QuartzCore/CAMetalLayer/nextDrawable()) return `nil`.

### Releasing the Drawable

Don’t release the drawable explicitly; instead, embed your render loop within an autorelease pool block:

```swift
func draw(in view: MTKView) {
    autoreleasepool {
        render(view: view)
    }
}
```

This block releases drawables promptly and avoids possible deadlock situations with multiple drawables. Release drawables as soon as possible after committing your onscreen render pass.

> Note:
> As of iOS 10 and tvOS 10, you can safely retain a drawable to query its properties, such as <doc://com.apple.documentation/documentation/Metal/MTLDrawable/drawableID> and <doc://com.apple.documentation/documentation/Metal/MTLDrawable/presentedTime>, after the system has presented it. If you don’t need to query these properties, release the drawable when you no longer need it.

## Topics

### Configuring the Metal Device

[`var device: (any MTLDevice)?`](/documentation/QuartzCore/CAMetalLayer/device)

The Metal device responsible for the layer’s drawable resources.

[`var preferredDevice: (any MTLDevice)?`](/documentation/QuartzCore/CAMetalLayer/preferredDevice)

The device object that the system recommends using for this layer.

### Configuring the Layer’s Drawable Objects

[`var pixelFormat: MTLPixelFormat`](/documentation/QuartzCore/CAMetalLayer/pixelFormat)

The pixel format of the layer’s textures.

[`var colorspace: CGColorSpace?`](/documentation/QuartzCore/CAMetalLayer/colorspace)

The color space of the rendered content.

[`var framebufferOnly: Bool`](/documentation/QuartzCore/CAMetalLayer/framebufferOnly)

A Boolean value that determines whether the layer’s textures are used only for rendering.

[`var drawableSize: CGSize`](/documentation/QuartzCore/CAMetalLayer/drawableSize)

The size, in pixels, of textures for rendering layer content.

### Configuring Presentation Behavior

[`var presentsWithTransaction: Bool`](/documentation/QuartzCore/CAMetalLayer/presentsWithTransaction)

A Boolean value that determines whether the layer presents its content using a Core Animation transaction.

[`var displaySyncEnabled: Bool`](/documentation/QuartzCore/CAMetalLayer/displaySyncEnabled)

A Boolean value that determines whether the layer synchronizes its updates to the display’s refresh rate.

### Configuring Extended Dynamic Range Behavior

[`var wantsExtendedDynamicRangeContent: Bool`](/documentation/QuartzCore/CAMetalLayer/wantsExtendedDynamicRangeContent)

Enables extended dynamic range values onscreen.

[`var edrMetadata: CAEDRMetadata?`](/documentation/QuartzCore/CAMetalLayer/edrMetadata)

Metadata describing the tone mapping to apply to the extended dynamic range (EDR) values in the layer.

### Obtaining a Metal Drawable

[`func nextDrawable() -> (any CAMetalDrawable)?`](/documentation/QuartzCore/CAMetalLayer/nextDrawable())

Waits until a Metal drawable is available, and then returns it.

[`var maximumDrawableCount: Int`](/documentation/QuartzCore/CAMetalLayer/maximumDrawableCount)

The number of Metal drawables in the resource pool managed by Core Animation.

[`var allowsNextDrawableTimeout: Bool`](/documentation/QuartzCore/CAMetalLayer/allowsNextDrawableTimeout)

A Boolean value that determines whether requests for a new buffer expire if the system can’t satisfy them.

### Configuring the Metal Performance HUD

[`var developerHUDProperties: [AnyHashable : Any]?`](/documentation/QuartzCore/CAMetalLayer/developerHUDProperties)

The properties of the Metal performance heads-up display.

### Instance Properties

[`var residencySet: any MTLResidencySet`](/documentation/QuartzCore/CAMetalLayer/residencySet)

## Relationships

### Conforms To

[`CustomDebugStringConvertible`](/documentation/Swift/CustomDebugStringConvertible)

[`NSSecureCoding`](/documentation/Foundation/NSSecureCoding)

[`CAMediaTiming`](/documentation/QuartzCore/CAMediaTiming)

[`CustomStringConvertible`](/documentation/Swift/CustomStringConvertible)

[`NSCoding`](/documentation/Foundation/NSCoding)

[`CVarArg`](/documentation/Swift/CVarArg)

[`Equatable`](/documentation/Swift/Equatable)

[`Hashable`](/documentation/Swift/Hashable)

[`SendableMetatype`](/documentation/Swift/SendableMetatype)

[`NSObjectProtocol`](/documentation/ObjectiveC/NSObjectProtocol)

[`Sendable`](/documentation/Swift/Sendable)

### Inherits From

[`CALayer`](/documentation/QuartzCore/CALayer)

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)