pub struct IOSurface(/* private fields */);Expand description
Hardware-accelerated surface for efficient frame delivery
IOSurface is Apple’s cross-process framebuffer type. It provides:
- Zero-copy sharing between processes
- Direct GPU texture creation via Metal
- Multi-planar format support (YCbCr, etc.)
§Memory Access Safety
The surface must be locked before accessing pixel data. Use lock
to get a RAII guard that ensures proper locking/unlocking.
§Examples
use screencapturekit::cm::{IOSurface, IOSurfaceLockOptions};
fn access_surface(surface: &IOSurface) -> Result<(), i32> {
// Lock for read-only access
let guard = surface.lock(IOSurfaceLockOptions::READ_ONLY)?;
// Access pixel data through the guard
let data = guard.as_slice();
println!("Surface has {} bytes", data.len());
// Surface automatically unlocked when guard drops
Ok(())
}Implementations§
Source§impl IOSurface
impl IOSurface
Sourcepub fn create(
width: usize,
height: usize,
pixel_format: u32,
bytes_per_element: usize,
) -> Option<Self>
pub fn create( width: usize, height: usize, pixel_format: u32, bytes_per_element: usize, ) -> Option<Self>
Create a new IOSurface with the given dimensions and pixel format
§Arguments
width- Width in pixelsheight- Height in pixelspixel_format- Pixel format as aFourCCcode (e.g., 0x42475241 for ‘BGRA’)bytes_per_element- Bytes per pixel (e.g., 4 for BGRA)
§Returns
Some(IOSurface) if creation succeeded, None otherwise.
§Examples
use screencapturekit::cm::IOSurface;
// Create a 100x100 BGRA IOSurface
let surface = IOSurface::create(100, 100, 0x42475241, 4)
.expect("Failed to create IOSurface");
assert_eq!(surface.width(), 100);
assert_eq!(surface.height(), 100);Sourcepub fn create_with_properties(
width: usize,
height: usize,
pixel_format: u32,
bytes_per_element: usize,
bytes_per_row: usize,
alloc_size: usize,
planes: Option<&[PlaneProperties]>,
) -> Option<Self>
pub fn create_with_properties( width: usize, height: usize, pixel_format: u32, bytes_per_element: usize, bytes_per_row: usize, alloc_size: usize, planes: Option<&[PlaneProperties]>, ) -> Option<Self>
Create an IOSurface with full properties including multi-planar support
This is the general API for creating IOSurfaces with any pixel format,
including multi-planar formats like YCbCr 4:2:0.
§Arguments
width- Width in pixelsheight- Height in pixelspixel_format- Pixel format asFourCC(e.g., 0x42475241 for BGRA)bytes_per_element- Bytes per pixel elementbytes_per_row- Bytes per row (should be 16-byte aligned for Metal)alloc_size- Total allocation size in bytesplanes- Optional slice of plane info for multi-planar formats
§Examples
use screencapturekit::cm::iosurface::PlaneProperties;
use screencapturekit::cm::IOSurface;
// Create a YCbCr 420v biplanar surface
let width = 1920usize;
let height = 1080usize;
let plane0_bpr = (width + 15) & !15; // 16-byte aligned
let plane1_bpr = (width + 15) & !15;
let plane0_size = plane0_bpr * height;
let plane1_size = plane1_bpr * (height / 2);
let planes = [
PlaneProperties {
width,
height,
bytes_per_row: plane0_bpr,
bytes_per_element: 1,
offset: 0,
size: plane0_size,
},
PlaneProperties {
width: width / 2,
height: height / 2,
bytes_per_row: plane1_bpr,
bytes_per_element: 2,
offset: plane0_size,
size: plane1_size,
},
];
let surface = IOSurface::create_with_properties(
width,
height,
0x34323076, // '420v'
1,
plane0_bpr,
plane0_size + plane1_size,
Some(&planes),
);Sourcepub unsafe fn from_ptr(ptr: *mut c_void) -> Self
pub unsafe fn from_ptr(ptr: *mut c_void) -> Self
§Safety
The caller must ensure the pointer is a valid IOSurface pointer.
Sourcepub fn bytes_per_row(&self) -> usize
pub fn bytes_per_row(&self) -> usize
Get the bytes per row of the surface
Sourcepub fn alloc_size(&self) -> usize
pub fn alloc_size(&self) -> usize
Get the total allocation size of the surface in bytes
Sourcepub fn data_size(&self) -> usize
pub fn data_size(&self) -> usize
Get the data size of the surface in bytes (alias for alloc_size)
This method provides API parity with CVPixelBuffer::data_size().
Sourcepub fn pixel_format(&self) -> u32
pub fn pixel_format(&self) -> u32
Get the pixel format of the surface (OSType/FourCC)
Sourcepub fn seed(&self) -> u32
pub fn seed(&self) -> u32
Get the modification seed value
This value changes each time the surface is modified, useful for detecting whether the surface contents have changed.
Sourcepub fn plane_count(&self) -> usize
pub fn plane_count(&self) -> usize
Get the number of planes in this surface
Multi-planar formats like YCbCr 420 have multiple planes:
- Plane 0: Y (luminance)
- Plane 1:
CbCr(chrominance)
Single-plane formats like BGRA return 0.
Sourcepub fn width_of_plane(&self, plane_index: usize) -> usize
pub fn width_of_plane(&self, plane_index: usize) -> usize
Get the width of a specific plane
For YCbCr 4:2:0 formats, plane 1 (CbCr) is half the width of plane 0 (Y).
Sourcepub fn height_of_plane(&self, plane_index: usize) -> usize
pub fn height_of_plane(&self, plane_index: usize) -> usize
Get the height of a specific plane
For YCbCr 4:2:0 formats, plane 1 (CbCr) is half the height of plane 0 (Y).
Sourcepub fn bytes_per_row_of_plane(&self, plane_index: usize) -> usize
pub fn bytes_per_row_of_plane(&self, plane_index: usize) -> usize
Get the bytes per row of a specific plane
Sourcepub fn bytes_per_element(&self) -> usize
pub fn bytes_per_element(&self) -> usize
Get the bytes per element of the surface
Sourcepub fn element_width(&self) -> usize
pub fn element_width(&self) -> usize
Get the element width of the surface
Sourcepub fn element_height(&self) -> usize
pub fn element_height(&self) -> usize
Get the element height of the surface
Sourcepub fn increment_use_count(&self)
pub fn increment_use_count(&self)
Increment the use count of the surface
Sourcepub fn decrement_use_count(&self)
pub fn decrement_use_count(&self)
Decrement the use count of the surface
Sourcepub fn unlock_raw(&self, options: IOSurfaceLockOptions) -> Result<u32, i32>
pub fn unlock_raw(&self, options: IOSurfaceLockOptions) -> Result<u32, i32>
Sourcepub fn lock(
&self,
options: IOSurfaceLockOptions,
) -> Result<IOSurfaceLockGuard<'_>, i32>
pub fn lock( &self, options: IOSurfaceLockOptions, ) -> Result<IOSurfaceLockGuard<'_>, i32>
Lock the surface and return a guard for RAII-style access
This is the recommended way to access surface memory. The guard ensures the surface is properly unlocked when it goes out of scope.
§Arguments
options- Lock options (e.g.,IOSurfaceLockOptions::READ_ONLY)
§Errors
Returns kern_return_t error code if the lock fails.
§Examples
use screencapturekit::cm::{IOSurface, IOSurfaceLockOptions};
fn read_surface(surface: &IOSurface) -> Result<(), i32> {
let guard = surface.lock(IOSurfaceLockOptions::READ_ONLY)?;
let data = guard.as_slice();
println!("Read {} bytes", data.len());
Ok(())
}Sourcepub fn lock_read_only(&self) -> Result<IOSurfaceLockGuard<'_>, i32>
pub fn lock_read_only(&self) -> Result<IOSurfaceLockGuard<'_>, i32>
Lock the surface for read-only access
This is a convenience method equivalent to lock(IOSurfaceLockOptions::READ_ONLY).
§Errors
Returns kern_return_t error code if the lock fails.
Sourcepub fn lock_read_write(&self) -> Result<IOSurfaceLockGuard<'_>, i32>
pub fn lock_read_write(&self) -> Result<IOSurfaceLockGuard<'_>, i32>
Lock the surface for read-write access
This is a convenience method equivalent to lock(IOSurfaceLockOptions::NONE).
§Errors
Returns kern_return_t error code if the lock fails.
Source§impl IOSurface
impl IOSurface
Sourcepub fn info(&self) -> IOSurfaceInfo
pub fn info(&self) -> IOSurfaceInfo
Get detailed information about this IOSurface for Metal texture creation
Sourcepub fn is_ycbcr_biplanar(&self) -> bool
pub fn is_ycbcr_biplanar(&self) -> bool
Check if this IOSurface uses a YCbCr biplanar format
Source§impl IOSurface
impl IOSurface
Sourcepub fn texture_params(&self) -> Vec<TextureParams>
pub fn texture_params(&self) -> Vec<TextureParams>
Get texture parameters for creating Metal textures from this IOSurface
Returns texture parameters for each plane needed to render this surface.
- Single-plane formats (BGRA, L10R): Returns 1 texture param
- YCbCr biplanar formats: Returns 2 texture params (Y and
CbCrplanes)
Source§impl IOSurface
impl IOSurface
Sourcepub fn metal_textures<T, F>(
&self,
create_texture: F,
) -> Option<CapturedTextures<T>>
pub fn metal_textures<T, F>( &self, create_texture: F, ) -> Option<CapturedTextures<T>>
Create Metal textures from this IOSurface using a closure
This is a zero-copy operation - the textures share memory with the IOSurface.
The closure receives TextureParams and the raw IOSurfaceRef pointer,
and should return the created texture.
§Example
use screencapturekit::cm::IOSurface;
use std::ffi::c_void;
fn example(surface: &IOSurface) {
let textures = surface.metal_textures(|params, _iosurface_ptr| {
// Create Metal texture using params.width, params.height, params.format
// Return Some(texture) or None
Some(()) // placeholder
});
if let Some(textures) = textures {
if textures.is_ycbcr() {
// Use YCbCr shader with plane0 (Y) and plane1 (CbCr)
}
}
}§Safety
The closure receives a raw IOSurfaceRef pointer. The pointer is valid
for the duration of the closure call.
Source§impl IOSurface
impl IOSurface
Sourcepub fn create_metal_textures(
&self,
device: &MetalDevice,
) -> Option<MetalCapturedTextures>
pub fn create_metal_textures( &self, device: &MetalDevice, ) -> Option<MetalCapturedTextures>
Create Metal textures from this IOSurface using the provided device
This is a zero-copy operation - the textures share memory with the IOSurface.
§Example
use screencapturekit::metal::MetalDevice;
use screencapturekit::cm::IOSurface;
fn example(surface: &IOSurface) {
let device = MetalDevice::system_default().expect("No Metal device");
if let Some(textures) = surface.create_metal_textures(&device) {
if textures.is_ycbcr() {
// Use YCbCr shader with plane0 (Y) and plane1 (CbCr)
}
}
}