pixel_surface 1.0.0
pixel_surface: ^1.0.0 copied to clipboard
Flutter GPU texture runtime — TextureRegistry bridge, CVPixelBuffer / SurfaceTexture upload, and GpuTextureView. No editor, filters, or beauty.
pixel_surface #
Flutter GPU Texture runtime — register a platform texture, upload RGBA / BGRA frames, and display with GpuTextureView. Includes a PixelBufferPool for texture recycling and automatic memory-pressure handling on iOS, macOS, and Android.
Platform Support #
| Platform | Support | Notes |
|---|---|---|
| Android | Yes | API 21+, SurfaceTexture; decodePreviewToSurface (MediaCodec zero-copy) |
| iOS | Yes | 12+, CVPixelBuffer; vImage swizzle for RGBA |
| macOS | Yes | 12+, CVPixelBuffer; vImage swizzle for RGBA |
| Linux | No | Use an RGBA widget fallback in your app |
| Windows | No | Use an RGBA widget fallback in your app |
| Web | No | Use an RGBA widget fallback in your app |
Rust / NDK: not required for this package alone.
Quick Start #
import 'package:pixel_surface/pixel_surface.dart';
const handle = 1;
final textureId = await GpuTextureRegistry.createTexture(
handle: handle,
width: 512,
height: 512,
);
// RGBA (default) or BGRA — BGRA is a single memcpy on Apple, no channel swap.
await GpuTextureRegistry.updateTextureBgra(
handle: handle,
pixels: bgra8888,
);
GpuTextureView(textureId: textureId!, width: 512, height: 512);
Method channel: pixel_surface/texture.
What You Can Do #
- Cross-platform texture registration — single
createTexture/updateTexture/disposeTextureAPI. - RGBA & BGRA uploads —
updateTexture(RGBA) andupdateTextureBgra(single memcpy, no channel swap).PixelLayoutenum for the format. **presentPixelBuffer** — zero-copy blit of a VideoToolbox decode buffer into the IOSurface / Metal-compatible texture backing (fixes FlutterCVReturn -6660).**decodePreviewToSurface**— Android MediaCodec → FlutterSurfaceTexture(V1.6).**GpuTextureViewwidget** — GPU-resident frame display, noRepaintBoundaryround-trip.- Texture recycling (
PixelBufferPool) — keyed by(width, height, pixelFormat)with 3 warm buffers per bucket.resizeTextureandflushPoolsfor cross-platform memory pressure handling. - Memory-pressure hooks — Apple
didReceiveMemoryWarning+thermalStateDidChange; AndroidComponentCallbacks2.onTrimMemory(levelsRUNNING_MODERATE/RUNNING_LOW/RUNNING_CRITICAL/UI_HIDDEN/BACKGROUND/MODERATE/COMPLETE). **debugStats()** —PixelSurfaceStatswithhandleCount,poolCount,createCount,lastFlushMs,lastMemoryWarningMs,trimEventCount,recycledBitmapCount,lastTrimLevel.- RAII safety —
BeautyOutputTargettyped wrapper for adopting a Flutter-sideCVPixelBuffer+MTLTexturepair into a wgpu pipeline. Closes the originalCVMetalTextureRefleak. **kCVPixelBufferMetalCompatibilityKey** set on every texture allocation.- Modern Flutter — uses
TextureRegistry.SurfaceProducer+scheduleFrame()(Flutter 3.27+;markTextureFrameAvailableremoved).
Installation #
flutter pub add pixel_surface
No Rust toolchain or NDK is required to consume this package on its own. If you use the higher-level beauty / GPU pipeline, you'll also want image_forge.
More Examples #
GpuTextureView #
GpuTextureView(
textureId: textureId!,
width: 512,
height: 512,
fit: BoxFit.contain,
)
Present a CVPixelBuffer (zero-copy) #
await GpuTextureRegistry.presentPixelBuffer(
handle: handle,
pixelBuffer: vtDecodedBuffer,
);
Memory pressure #
// Recycle every backing bitmap and CVMetalTextureCache
await GpuTextureRegistry.flushPools();
// Inspect operator-facing counters
final stats = await GpuTextureRegistry.debugStats();
print('last trim level: ${stats.lastTrimLevel}');
Resize a texture #
await GpuTextureRegistry.resizeTexture(
handle: handle,
width: 1024,
height: 1024,
);
Contributing #
This package is part of the MediaForge monorepo. Issues and pull requests are welcome on GitHub.