7 releases (4 breaking)

0.5.0 Dec 26, 2023
0.4.0-dev2 Nov 29, 2023
0.3.0 Jul 28, 2023
0.2.0 Jul 1, 2023
0.1.1 Nov 16, 2022

#468 in GUI

MIT license

205KB
5K SLoC

irondash_texture

Platform agnostic (as much as possible) interface to Flutter external textures.

Core idea is to implement PayloadProvider trait for your object that provides texture data and then create Texture for the provider:

struct MyPayloadProvider {
    // ...
}

impl PayloadProvider<BoxedPixelData> for MyPayloadProvider {
    // This method will be called by Flutter during rasterization
    // to get new texture data.
    fn get_payload(&self) -> BoxedPixelData {
        let data: Vec<u8> = make_pixel_data(width, height);
        SimplePixelData::boxed(width, height, data)
    }
}

After you have PayloadProvider you can create Texture:

let provider = Arc::new(MyPayloadProvider::new());
let texture = Texture::new_with_provider(engine_handle, provider)?;

let id = texture.id(); // pass this ID back to Flutter to create Texture widget.

/// This tells Flutter that it should refresh the texture and redraw frame.
texture.mark_frame_available();

To create texture, you need to have handle for current Flutter engine, which you can obtain through irondash_engine_context.

BoxedPixelData payload type is supported on all platforms, though pixel order may change depending on platform. To find out pixel order for current platform use PixelData::FORMAT.

Other than BoxedPixelData, there are platform specific payload types that can be used to display GPU texture.

  • BoxedIOSurface that provides IOSurface texture on macOS and iOS
  • BoxedGLTexture on Linux
  • BoxedTextureDescriptor<ID3D11Texture2D> and BoxedTextureDescriptor<DxgiSharedHandle> on Windows

To use GPU texture on Android, instead of setting payload, you can request JNI Surface or NDK ANativeWindow from the texture:

let texture = Texture::<NativeWindow>::new(engine_handle)?;
let native_window = texture.get()?;

Threading

PayloadProvider must be Send and Sync, the texture payload will be requested on raster thread.

Texture itself must be created on platform thread. However once the texture is created, you can convert it to SendableTexture, which can be moved between threads:

let texture = Texture::new_with_provider(engine_handle, provider)?;
let texture = texture.into_sendable_texture();

thread::spawn(move||{
    // texture can now be used from any thread.
    texture.mark_frame_available();
});

Dependencies

~0.8–15MB
~157K SLoC