IOSurface

Struct IOSurface 

Source
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

Source

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 pixels
  • height - Height in pixels
  • pixel_format - Pixel format as a FourCC code (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);
Source

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 pixels
  • height - Height in pixels
  • pixel_format - Pixel format as FourCC (e.g., 0x42475241 for BGRA)
  • bytes_per_element - Bytes per pixel element
  • bytes_per_row - Bytes per row (should be 16-byte aligned for Metal)
  • alloc_size - Total allocation size in bytes
  • planes - 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),
);
Source

pub fn from_raw(ptr: *mut c_void) -> Option<Self>

Create from raw pointer

Source

pub unsafe fn from_ptr(ptr: *mut c_void) -> Self

§Safety

The caller must ensure the pointer is a valid IOSurface pointer.

Source

pub fn as_ptr(&self) -> *mut c_void

Get the raw pointer

Source

pub fn width(&self) -> usize

Get the width of the surface in pixels

Source

pub fn height(&self) -> usize

Get the height of the surface in pixels

Source

pub fn bytes_per_row(&self) -> usize

Get the bytes per row of the surface

Source

pub fn alloc_size(&self) -> usize

Get the total allocation size of the surface in bytes

Source

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().

Source

pub fn pixel_format(&self) -> u32

Get the pixel format of the surface (OSType/FourCC)

Source

pub fn id(&self) -> u32

Get the unique IOSurfaceID for this surface

Source

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.

Source

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.

Source

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).

Source

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).

Source

pub fn bytes_per_row_of_plane(&self, plane_index: usize) -> usize

Get the bytes per row of a specific plane

Source

pub fn bytes_per_element(&self) -> usize

Get the bytes per element of the surface

Source

pub fn element_width(&self) -> usize

Get the element width of the surface

Source

pub fn element_height(&self) -> usize

Get the element height of the surface

Source

pub fn is_in_use(&self) -> bool

Check if the surface is currently in use

Source

pub fn increment_use_count(&self)

Increment the use count of the surface

Source

pub fn decrement_use_count(&self)

Decrement the use count of the surface

Source

pub fn lock_raw(&self, options: IOSurfaceLockOptions) -> Result<u32, i32>

Lock the surface for CPU access (low-level API)

Prefer using lock for RAII-style access.

§Arguments
  • options - Lock options (e.g., IOSurfaceLockOptions::READ_ONLY)
§Errors

Returns kern_return_t error code if the lock fails.

Source

pub fn unlock_raw(&self, options: IOSurfaceLockOptions) -> Result<u32, i32>

Unlock the surface after CPU access (low-level API)

§Arguments
  • options - Must match the options used in the corresponding lock_raw() call
§Errors

Returns kern_return_t error code if the unlock fails.

Source

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(())
}
Source

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.

Source

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

Source

pub fn info(&self) -> IOSurfaceInfo

Get detailed information about this IOSurface for Metal texture creation

Source

pub fn is_ycbcr_biplanar(&self) -> bool

Check if this IOSurface uses a YCbCr biplanar format

Source§

impl IOSurface

Source

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 CbCr planes)
Source§

impl IOSurface

Source

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

Source

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)
        }
    }
}

Trait Implementations§

Source§

impl Clone for IOSurface

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for IOSurface

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for IOSurface

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for IOSurface

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Hash for IOSurface

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for IOSurface

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for IOSurface

Source§

impl Send for IOSurface

Source§

impl Sync for IOSurface

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.