Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Consider exposing plugin APIs for use via FFI #110353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
stuartmorgan-g opened this issue Aug 26, 2022 · 14 comments
Open

Consider exposing plugin APIs for use via FFI #110353

stuartmorgan-g opened this issue Aug 26, 2022 · 14 comments
Labels
a: plugins Support for writing, building, and running plugin packages c: new feature Nothing broken; request for a new capability engine flutter/engine repository. See also e: labels. P3 Issues that are less important to the Flutter project team-engine Owned by Engine team triaged-engine Triaged by Engine team

Comments

@stuartmorgan-g
Copy link
Contributor

Currently FFI can be used as an alternative to normal plugin structure for some use cases, but anything that requires access to plugin APIs—things exposed via the plugin registry, such as texture registration, or accessing the native view on desktop—requires using the normal plugin flow and method channels.

We should investigate whether there's a reasonable way to expose at least some of that functionality via APIs that are accessible via FFI.

As an example use case, if we wanted to convert file_selector_windows it should be mostly doable via the win32 package, but we need access to the native HWND to show the dialog in the correct location, and that's currently only accessible via the plugin registry.

@stuartmorgan-g stuartmorgan-g added c: new feature Nothing broken; request for a new capability engine flutter/engine repository. See also e: labels. plugin P3 Issues that are less important to the Flutter project labels Aug 26, 2022
@timsneath
Copy link
Contributor

@stuartmorgan-g
Copy link
Contributor Author

In the particular case of this one API in this one use case, you could get correct behavior in most cases by guessing that the active window is the one showing the dialog. There's no guarantee that that's true though.

And it definitely doesn't generalize to, for instance, the texture registry.

@stuartmorgan-g stuartmorgan-g added a: plugins Support for writing, building, and running plugin packages and removed plugin labels Mar 6, 2023
@flutter-triage-bot flutter-triage-bot bot added team-engine Owned by Engine team triaged-engine Triaged by Engine team labels Jul 8, 2023
@talksik
Copy link

talksik commented Jul 22, 2023

I am going down a big rabbit hole, because I don't understand graphics or the flutter engine too well. Would appreciate any help at all :)

I was going to use FFI from flutter/dart to my rust code that captures video frames using gstreamer. With rust, I want to stream frames/pixel buffers to the texture registry. I need to render local video and then as an extension should be able to render incoming UDP bytes using the same pattern.

Am I correct that based on this discussion, that I am down the wrong path? Would you suggest some sort of workaround?

Thank you so much!

@stuartmorgan-g
Copy link
Contributor Author

Am I correct that based on this discussion, that I am down the wrong path?

There is currently no built-in way to access the texture registry directly from FFI, nor are they threadsafe unless specfically noted (and FFI calls will not run on the platform thread).

Would you suggest some sort of workaround?

You could either write a standard Flutter plugin that calls your Rust code, or you could design your own system in native code for making tetxtures accessible to FFI (e.g., by indirecting through a global that you design that store references and manages cross-thread dispatching).

@talksik

This comment was marked as off-topic.

@lattice0
Copy link

This would help development a lot, the only kotlin part of my android app is for texture registry

josxha added a commit to josxha/flutter-maplibre that referenced this issue Jul 5, 2024
dart:ffi has currently only basic interop and can't be used for textures.
- flutter/flutter#52229
- flutter/flutter#110353
@liamappelbe
Copy link
Contributor

What are the blockers for this? It sounds like one issue is thread safety, but we have runOnPlatformThread now.

@stuartmorgan-g
Copy link
Contributor Author

It needs a design for what exactly we are going to expose (e.g., is it the entire registrar surface? how do we adapt the API given that it's designed as a per-plugin interface, but there's no plugin instance in this use case? or do we require a dartPluginClass and use a similar structure to plugins where registrar instances are pushed to Dart plugin instances?) and how we want to plumb access to an entry point into the engine.

@stuartmorgan-g
Copy link
Contributor Author

Here is the set of issues I've identified that would need to be resolved in order to use the texture APIs on iOS entirely via FFI, with no plugin component (a subset of this issue, but an illustrative one):

  • There is no mechanism to get access to the plugin registrar object from Dart. There are a few ways we could handle this, but I think my preferred option would be to change the Dart registerWith function to get an object (this is a breaking change, but that's pretty easy to mitigate with min SDK checks).
  • ffigen needs to be able to be pointed to Flutter.h. Right now we put the framework in the right place as an internal detail of the build, but ffigen is a user-run, user-configured step, so we would likely need a new tool "API" in the form of putting (or at least linking to) Flutter.h in a stable, documented location.
  • copyPixelBuffer is called on the raster thread. Implementing that in Dart would require a native trampoline to a different thread since (unless I'm mistaken) the raster thread doesn't have a Dart isolate. ffigen can create trampolines to block callbacks, but I believe they always bounce to the main isolate's thread, and moving all texture copying to that thread is very likely undesirable. We'd need a pattern for how to easily move from a non-main native thread to a non-main Dart isolate.

I'll flesh this out more in a design document, where we can explore technical solutions and file more specific follow-up issues, but I wanted to capture the issues here at a high level.

@liamappelbe
Copy link
Contributor

  • ffigen can create trampolines to block callbacks, but I believe they always bounce to the main isolate's thread, and moving all texture copying to that thread is very likely undesirable.

Just to clarify, NativeCallable.listener creates a NativeCallable that will bounce to whatever isolate created it, and you can create them in any isolate. ffigen builds on this capability to generate ObjC blocks that also bounce to whatever isolate created them.

@stuartmorgan-g
Copy link
Contributor Author

Ah, thanks for clearing up my misunderstanding! I'll play around with trying to find a pattern for driving the texture updates from a background isolate.

@stuartmorgan-g
Copy link
Contributor Author

I'll play around with trying to find a pattern for driving the texture updates from a background isolate.

I ran into a dead-end on this because copyPixelBuffer is a synchronous function. The way the native code handles this that copyPixelBuffer does a blocking dispatch to the background dispatch queue that both does the video stream extraction and guarantees safe multi-threaded access to the resulting buffer. Without blocking isolate dispatch, or some kind of shared memory+lock primitives, I don't think the iOS FlutterTexture pattern can be implemented in Dart.

@liamappelbe
Copy link
Contributor

What sort of stuff would that callback need to do? Would it run arbitrary user code, or code that the flutter team owns? @aam is working on a variant of NativeCallable called isolateGroupShared that is blocking and can be invoked from any thread, but has a bunch of restrictions about what it's allowed to do. If we are writing that callback we can work within those restrictions, but users might find it tricky. Tracking bug (the API name has changed a few times).

@stuartmorgan-g
Copy link
Contributor Author

This is a plugin API, so the code is arbitrary user code. In practice, I would guess that the use cases for the texture API would mostly be similar to what video_player needs, which is as described in the previous comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: plugins Support for writing, building, and running plugin packages c: new feature Nothing broken; request for a new capability engine flutter/engine repository. See also e: labels. P3 Issues that are less important to the Flutter project team-engine Owned by Engine team triaged-engine Triaged by Engine team
Projects
None yet
Development

No branches or pull requests

5 participants