Mac Developer Library

Developer

IOSurfaceAPI.h Reference

Options
Deployment Target:

On This Page

IOSurfaceAPI.h Reference

The IOSurfaceAPI header contains the public API for the IOSurface framework. The IOSurface framework provides a framebuffer object suitable for sharing across process boundaries. It is commonly used to allow applications to move complex image decompression and draw logic into a separate process to enhance security.

Included Headers

  • <IOKit/IOKitLib.h>

  • <IOSurface/IOSurfaceBase.h>

Functions

There are cases where it is useful to know whether or not an IOSurface buffer is considered to be "in use" by other users of the same IOSurface. In particular, CoreVideo and other APIs make use of the IOSurface use count facility to know when it is safe to recycle an IOSurface backed CVPixelBuffer object. This is particularly important when IOSurface objects are being shared across process boundaries and the normal mechanisms one might use would not be viable.

The IOSurface use count is similar in concept to any other reference counting scheme. When the global use count of an IOSurface goes to zero, it is no longer considered "in use". When it is anything other than zero, then the IOSurface is still "in use" by someone and therefore anyone attempting to maintain a pool of IOSurfaces to be recycled should not reclaim that IOSurface.

Note that IOSurface maintains both a per-process and an internal system wide usage count. In the current implementation, when the per-process usage count goes from zero to one, the system wide usage count is incremented by one. When the per-process usage count drops back to zero (either via explicit decrement calls or the process terminates), the global usage count is decremented by one.

IOSurfaceGetUseCount() returns the local per-process usage count for an IOSurface. This call is only provided for logging/debugging purposes and should never be used to determine whether an IOSurface is considered to be "in use". IOSurfaceIsInUse() is the only call that should be used for that purpose.

These functions return various properties of a specific plane within a buffer, such as length, height, and so on.

  • Returns the address of the first byte of data in the specified plane.

    Declaration

    void *IOSurfaceGetBaseAddressOfPlane( IOSurfaceRef buffer, size_t planeIndex) ;

    Discussion

    If the planeIndex is greater than or equal to the plane count of the IOSurface, zero is returned.... with one exception. If this IOSurface has zero planes and a planeIndex of zero is passed in, the routines function just like the non-planar APIs. This is to allow higher level code to treat planar and non-planar buffers is a more uniform fashion.

  • Returns the size of each element (in bytes) in the specified plane.

    Declaration

    size_t IOSurfaceGetBytesPerElementOfPlane( IOSurfaceRef buffer, size_t planeIndex) ;

    Discussion

    If the planeIndex is greater than or equal to the plane count of the IOSurface, zero is returned.... with one exception. If this IOSurface has zero planes and a planeIndex of zero is passed in, the routines function just like the non-planar APIs. This is to allow higher level code to treat planar and non-planar buffers is a more uniform fashion.

  • Returns the size of each row (in bytes) in the specified plane.

    Declaration

    size_t IOSurfaceGetBytesPerRowOfPlane( IOSurfaceRef buffer, size_t planeIndex) ;

    Discussion

    If the planeIndex is greater than or equal to the plane count of the IOSurface, zero is returned.... with one exception. If this IOSurface has zero planes and a planeIndex of zero is passed in, the routines function just like the non-planar APIs. This is to allow higher level code to treat planar and non-planar buffers is a more uniform fashion.

  • Returns the height (in pixels) of each element in the specified plane.

    Declaration

    size_t IOSurfaceGetElementHeightOfPlane( IOSurfaceRef buffer, size_t planeIndex) ;

    Discussion

    If the planeIndex is greater than or equal to the plane count of the IOSurface, zero is returned.... with one exception. If this IOSurface has zero planes and a planeIndex of zero is passed in, the routines function just like the non-planar APIs. This is to allow higher level code to treat planar and non-planar buffers is a more uniform fashion.

  • Returns the width (in pixels) of each element in the specified plane.

    Declaration

    size_t IOSurfaceGetElementWidthOfPlane( IOSurfaceRef buffer, size_t planeIndex) ;

    Discussion

    If the planeIndex is greater than or equal to the plane count of the IOSurface, zero is returned.... with one exception. If this IOSurface has zero planes and a planeIndex of zero is passed in, the routines function just like the non-planar APIs. This is to allow higher level code to treat planar and non-planar buffers is a more uniform fashion.

  • Returns the height of the specified plane (in pixels).

    Declaration

    size_t IOSurfaceGetHeightOfPlane( IOSurfaceRef buffer, size_t planeIndex) ;

    Discussion

    If the planeIndex is greater than or equal to the plane count of the IOSurface, zero is returned.... with one exception. If this IOSurface has zero planes and a planeIndex of zero is passed in, the routines function just like the non-planar APIs. This is to allow higher level code to treat planar and non-planar buffers is a more uniform fashion.

  • Returns the width of the specified plane (in pixels).

    Declaration

    size_t IOSurfaceGetWidthOfPlane( IOSurfaceRef buffer, size_t planeIndex) ;

    Discussion

    If the planeIndex is greater than or equal to the plane count of the IOSurface, zero is returned.... with one exception. If this IOSurface has zero planes and a planeIndex of zero is passed in, the routines function just like the non-planar APIs. This is to allow higher level code to treat planar and non-planar buffers is a more uniform fashion.

These functions return various buffer properties such as length, height, and so on.

  • Returns the total allocation size of the buffer including all planes.

    Declaration

    size_t IOSurfaceGetAllocSize( IOSurfaceRef buffer) ;

    Return Value

    Returns 0 if buffer is invalid.

  • Returns the address of the first byte of data in a particular buffer.

    Declaration

    void *IOSurfaceGetBaseAddress( IOSurfaceRef buffer) ;

    Return Value

    Returns NULL if buffer is invalid.

  • Returns the length (in bytes) of each element in a particular buffer.

    Declaration

    size_t IOSurfaceGetBytesPerElement( IOSurfaceRef buffer) ;

    Return Value

    Returns 0 if buffer is invalid.

  • Returns the length (in bytes) of each row in a particular buffer.

    Declaration

    size_t IOSurfaceGetBytesPerRow( IOSurfaceRef buffer) ;

    Return Value

    Returns 0 if buffer is invalid.

  • Returns the height (in pixels) of each element in a particular buffer.

    Declaration

    size_t IOSurfaceGetElementHeight( IOSurfaceRef buffer) ;

    Return Value

    Returns 0 if buffer is invalid.

  • Returns the width (in pixels) of each element in a particular buffer.

    Declaration

    size_t IOSurfaceGetElementWidth( IOSurfaceRef buffer) ;

    Return Value

    Returns 0 if buffer is invalid.

  • Returns the height of the IOSurface buffer in pixels.

    Declaration

    size_t IOSurfaceGetHeight( IOSurfaceRef buffer) ;

    Return Value

    Returns 0 if buffer is invalid.

  • Returns an unsigned integer that contains the traditional OS X buffer format.

    Declaration

    OSType IOSurfaceGetPixelFormat( IOSurfaceRef buffer) ;

    Return Value

    Returns 0 if buffer is invalid.

  • Declaration

    size_t IOSurfaceGetPlaneCount( IOSurfaceRef buffer) ;

    Discussion

    Return the number of planes in this buffer. May be 0. Returns 0 for an invalid or NULL buffer pointer.

  • Declaration

    uint32_t IOSurfaceGetSeed( IOSurfaceRef buffer) ;

    Discussion

    This will return the current seed value of the buffer and is a cheap call to make to see if the contents of the buffer have changed since the last lock/unlock.

  • Returns the width of the IOSurface buffer in pixels.

    Declaration

    size_t IOSurfaceGetWidth( IOSurfaceRef buffer) ;

    Return Value

    Returns 0 if buffer is invalid.

These functions can be used to obtain handles to IOSurface objects in a form suitable for passing through XPC or Mach IPC.

  • Returns the smallest aligned value greater than or equal to the specified value.

    Declaration

    size_t IOSurfaceAlignProperty( CFStringRef property, size_t value) ;

    Discussion

    For properties with no alignment requirements, the original value is returned.

  • Returns a mach_port_t that holds a reference to the IOSurface.

    Declaration

    mach_port_t IOSurfaceCreateMachPort( IOSurfaceRef buffer) ;

    Discussion

    This is useful if you need to atomically or securely pass an IOSurface to another task without making the surface global to the entire system. The returned port must be deallocated with mach_port_deallocate or the equivalent.

  • Returns an xpc_object_t that holds a reference to the IOSurface.

    Declaration

    xpc_object_t IOSurfaceCreateXPCObject( IOSurfaceRef aSurface) ;

  • Returns the alignment requirements for a property (if any).

    Declaration

    size_t IOSurfaceGetPropertyAlignment( CFStringRef property) ;

    Discussion

    If the property has no alignment requirement then this function returns 1. The following properties should always be aligned if you choose to calculate them yourself:

    • kIOSurfaceBytesPerRow

    • kIOSurfaceOffset

    • kIOSurfacePlaneBase

    • kIOSurfacePlaneOffset

    • kIOSurfacePlaneBytesPerRow

  • Returns the maximum value for a given property that is guaranteed to be compatible with all of the current devices (GPUs, etc.) in the system.

    Declaration

    size_t IOSurfaceGetPropertyMaximum( CFStringRef property) ;

    Discussion

    The most important values to obtain are:

    • kIOSurfaceBytesPerRow

    • kIOSurfaceWidth

    • kIOSurfaceHeight

    • kIOSurfacePlaneBytesPerRow

    • kIOSurfacePlaneWidth

    • kIOSurfacePlaneHeight

    For the width and height properties, the maximum values are the largest that are guaranteed to work for both reading and writing. In OpenGL terms this translates into the largest size that will work for both textures and render targets.

    This function returns 0 for properties that have no predefined limit or where the concept of a limit would be considered invalid (such as kIOSurfacePixelFormat).

  • Recreates an IOSurfaceRef from a mach port.

    Declaration

    IOSurfaceRef IOSurfaceLookupFromMachPort( mach_port_t port) ;

    Discussion

    This call takes a mach_port_t created via IOSurfaceCreatePort() and recreates an IOSurfaceRef from it.

  • Declaration

    IOSurfaceRef IOSurfaceLookupFromXPCObject( xpc_object_t xobj) ;

    Discussion

    This call takes an XPC object created via IOSurfaceCreateXPCObject() and recreates an IOSurfaceRef from it. Note: This call does NOT destroy the port.

These functions create new IOSurface buffers and lock and unlock those buffers.

  • Creates a brand new IOSurface object

    Declaration

    IOSurfaceRef IOSurfaceCreate( CFDictionaryRef properties) ;

  • Retrieves the unique IOSurfaceID value for an IOSurface

    Declaration

    IOSurfaceID IOSurfaceGetID( IOSurfaceRef buffer) ;

  • "Lock" an IOSurface for reading or writing.

    Declaration

    IOReturn IOSurfaceLock( IOSurfaceRef buffer, uint32_t options, uint32_t *seed) ;

    Discussion

    The term "lock" is used loosely in this context, and is simply used along with the "unlock" information to put a bound on CPU access to the raw IOSurface data.

    If the seed parameter is non-NULL, IOSurfaceLock() will store the buffer's internal modification seed value at the time you made the lock call. You can compare this value to a value returned previously to determine of the contents of the buffer has been changed since the last lock.

    In the case of IOSurfaceUnlock(), the seed value returned will be the internal seed value at the time of the unlock. If you locked the buffer for writing, this value will be incremented as the unlock is performed and the new value will be returned.

    See IOSurface lock flags for more information.

    Note: Locking and unlocking an IOSurface is not a particularly cheap operation, so care should be taken to avoid the calls whenever possible. The seed values are particularly useful for keeping a cache of the buffer contents.

  • Performs an atomic lookup and retain of an IOSurface by its IOSurfaceID.

    Declaration

    IOSurfaceRef IOSurfaceLookup( IOSurfaceID csid) ;

  • "Unlock" an IOSurface for reading or writing.

    Declaration

    IOReturn IOSurfaceUnlock( IOSurfaceRef buffer, uint32_t options, uint32_t *seed) ;

    Discussion

    The term "lock" is used loosely in this context, and is simply used along with the "unlock" information to put a bound on CPU access to the raw IOSurface data.

    If the seed parameter is non-NULL, IOSurfaceLock() will store the buffer's internal modification seed value at the time you made the lock call. You can compare this value to a value returned previously to determine of the contents of the buffer has been changed since the last lock.

    In the case of IOSurfaceUnlock(), the seed value returned will be the internal seed value at the time of the unlock. If you locked the buffer for writing, this value will be incremented as the unlock is performed and the new value will be returned.

    See the kIOSurfaceLock enums for more information.

    Note: Locking and unlocking an IOSurface is not a particularly cheap operation, so care should be taken to avoid the calls whenever possible. The seed values are particularly useful for keeping a cache of the buffer contents.

The functions in this group allow you to attach arbitrary CF property list type objects to an IOSurface buffer. These functions are computationally expensive, and should be used only when necessary.

  • Retrieves a value from the dictionary associated with the buffer.

    Declaration

    CFTypeRef IOSurfaceCopyValue( IOSurfaceRef buffer, CFStringRef key) ;

    Discussion

    This call lets you attach CF property list types to an IOSurface buffer. This call is expensive (it must essentially serialize the data into the kernel) and thus should be avoided whenever possible.

  • Deletes a value in the dictionary associated with the buffer.

    Declaration

    void IOSurfaceRemoveValue( IOSurfaceRef buffer, CFStringRef key) ;

    Discussion

    This call lets you attach CF property list types to an IOSurface buffer. This call is expensive (it must essentially serialize the data into the kernel) and thus should be avoided whenever possible.

  • Sets a value in the dictionary associated with the buffer.

    Declaration

    void IOSurfaceSetValue( IOSurfaceRef buffer, CFStringRef key, CFTypeRef value) ;

    Discussion

    This call lets you attach CF property list types to an IOSurface buffer. This call is expensive (it must essentially serialize the data into the kernel) and thus should be avoided whenever possible.

Data Types

See the Overview for header-level documentation.

  • An IOSurface identifier.

    Declaration

    typedef uint32_t IOSurfaceID;

    Import Statement

  • Data type representing an IOSurface opaque object.

    Declaration

    typedef struct __IOSurface *IOSurfaceRef;

    Import Statement

Constants

See the Overview for header-level documentation.

  • Declaration

    extern const CFStringRef kIOSurfaceAllocSize; extern const CFStringRef kIOSurfaceBytesPerElement; extern const CFStringRef kIOSurfaceBytesPerRow; extern const CFStringRef kIOSurfaceCacheMode; extern const CFStringRef kIOSurfaceElementHeight; extern const CFStringRef kIOSurfaceElementWidth; extern const CFStringRef kIOSurfaceHeight; extern const CFStringRef kIOSurfaceIsGlobal; extern const CFStringRef kIOSurfaceOffset; extern const CFStringRef kIOSurfacePixelFormat; extern const CFStringRef kIOSurfacePlaneBase; extern const CFStringRef kIOSurfacePlaneBytesPerElement; extern const CFStringRef kIOSurfacePlaneBytesPerRow; extern const CFStringRef kIOSurfacePlaneElementHeight; extern const CFStringRef kIOSurfacePlaneElementWidth; extern const CFStringRef kIOSurfacePlaneHeight; extern const CFStringRef kIOSurfacePlaneInfo; extern const CFStringRef kIOSurfacePlaneOffset; extern const CFStringRef kIOSurfacePlaneSize; extern const CFStringRef kIOSurfacePlaneWidth; extern const CFStringRef kIOSurfaceWidth;

    Constants

    • kIOSurfaceAllocSize

      Defaults to BufferHeight * BytesPerRow if not specified. Must be specified for dimensionless buffers.

    • kIOSurfaceBytesPerElement

      Default to 1.

    • kIOSurfaceBytesPerRow

      If not specified, IOSurface will first calculate the number full elements required on each row (by rounding up), multiplied by the bytes per element for this buffer. That value will then be appropriately aligned.

    • kIOSurfaceCacheMode

      Default is kIOMapDefaultCache.

    • kIOSurfaceElementHeight

      Defaults to 1.

    • kIOSurfaceElementWidth

      Defaults to 1.

    • kIOSurfaceHeight

      Required for planar IOSurfaces.

    • kIOSurfaceIsGlobal

    • kIOSurfaceOffset

      Defaults to 0.

    • kIOSurfacePixelFormat

    • kIOSurfacePlaneBase

      Optional, defaults to the plane offset

    • kIOSurfacePlaneBytesPerElement

      Optional, default is 1.

    • kIOSurfacePlaneBytesPerRow

      If not specified, IOSurface will first calculate the number full elements required on each row (by rounding up), multiplied by the bytes per element for this plane. That value will then be appropriately aligned.

    • kIOSurfacePlaneElementHeight

      Optional, default is 1.

    • kIOSurfacePlaneElementWidth

      Optional, default is 1.

    • kIOSurfacePlaneHeight

      Required for image planes.

    • kIOSurfacePlaneInfo

      The CFArray must have at least one entry.

    • kIOSurfacePlaneOffset

      If not specified then IOSurface will lay out each plane sequentially based on the previous plane's allocation size.

    • kIOSurfacePlaneSize

      Defaults to plane height * plane bytes per row if not specified.

    • kIOSurfacePlaneWidth

      Required for image planes.

    • kIOSurfaceWidth

      Required for planar IOSurfaces.

  • Declaration

    enum { /*! If you are not going to modify the data while you hold the lock, you should set this flag to avoid invalidating */ kIOSurfaceLockReadOnly = 0x00000001, /*! If you want to detect/avoid a potentially expensive paging operation (such as readback from a GPU to system memory ) */ kIOSurfaceLockAvoidSync = 0x00000002 };

    Constants

    • kIOSurfaceLockReadOnly

      If you are not going to modify the data while you hold the lock, you should set this flag to avoid invalidating any existing caches of the buffer contents. This flag should be passed both to the lock and unlock functions. Non-symmentrical usage of this flag will result in undefined behavior.

    • kIOSurfaceLockAvoidSync

      If you want to detect/avoid a potentially expensive paging operation (such as readback from a GPU to system memory) when you lock the buffer, you may include this flag. If locking the buffer requires a readback, the lock will fail with an error return of kIOReturnCannotLock.