Functions & Hooks

imageFromNativeBuffer

function imageFromNativeBuffer(buffer: UInt64, format?: PixelFormat): TgfxImage;

Wrap a platform hardware buffer - an AHardwareBuffer* on Android, a CVPixelBufferRef on iOS - as an image handle. Pass frame.getNativeBuffer().pointer.

Zero-copy and synchronous: the buffer is imported straight to a GPU texture, with no decode and no CPU round trip. For a stream of frames, keep the handle and call image.setNativeBuffer(...) per frame - native code imports the new buffer and replaces the registry entry, while the draw path resolves the stable handle every frame. Nothing is re-committed, replacement schedules a redraw, and an undrawn frame is superseded by the next rather than queued behind it. The previous buffer is released on replacement; do not write into a buffer while the handle still points at it.

Such a handle is not accounted against the decoded-pixel budget: the memory belongs to whoever produced the buffer.

A worklet, so a camera frame processor can call it directly: the buffer is only alive for the duration of the callback, so the handle has to be made where the frame is, not hopped to the JS thread first.

Parameters

buffer

UInt64

format?

PixelFormat = 'bt601-limited'

Returns

TgfxImage

Remarks

Unlike every other function here, this one does not share the memoised factory: a worklet gets its own copy of module state, so it builds a TgfxImageFactory per call. That is deliberate and cheap for the intended once-per-stream use, but it is not free - do not call it per frame. Use image.setNativeBuffer(...) for the second and every later buffer.

buffer is a raw pointer, and nothing here can check it. It is only valid for as long as its producer says it is - for a VisionCamera frame, the body of the onFrame callback. Passing a stale or already-released pointer is a use-after-free that will not throw: it imports whatever memory is now at that address. Never store one, never let one outlive the callback it came from, and release the producer's own reference (nativeBuffer.release()) only after this call, or setNativeBuffer, has returned.

On this page