Skip to content

Commit

Permalink
android: surface callback for impeller. fix #101
Browse files Browse the repository at this point in the history
requires flutter 3.24
  • Loading branch information
wang-bin committed Aug 26, 2024
1 parent 180f972 commit e67d3b7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 10 deletions.
8 changes: 5 additions & 3 deletions android/fvp_plugin.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 WangBin <wbsecg1 at gmail.com>
* Copyright (c) 2023-2024 WangBin <wbsecg1 at gmail.com>
*/
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Expand Down Expand Up @@ -60,7 +60,7 @@ extern "C"
JNIEXPORT void JNICALL
Java_com_mediadevkit_fvp_FvpPlugin_nativeSetSurface(JNIEnv *env, jobject thiz, jlong player_handle,
jlong tex_id, jobject surface, jint w, jint h, jboolean tunnel) {
if (!player_handle) {
if (!player_handle || !surface) {
if (auto it = players.find(tex_id); it != players.end()) {
auto& player = it->second;
auto s = player->surface;
Expand All @@ -69,13 +69,15 @@ Java_com_mediadevkit_fvp_FvpPlugin_nativeSetSurface(JNIEnv *env, jobject thiz, j
if (s) {
env->DeleteGlobalRef(surface);
}
} else {
clog << "player not found(already removed?) for textureId " + std::to_string(tex_id) + " surface " + std::to_string((intptr_t)surface) << endl;
}
return;
}
assert(surface && "null surface");
auto player = make_shared<TexturePlayer>(player_handle);
clog << __func__ << endl;
if (tunnel) {
if (tunnel) { // TODO: tunel via ffi + global var
player->surface = env->NewGlobalRef(surface);
player->setProperty("video.decoder", "surface=" + std::to_string((intptr_t)player->surface));
} else {
Expand Down
37 changes: 30 additions & 7 deletions android/src/main/java/com/mediadevkit/fvp/FvpPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import io.flutter.view.TextureRegistry.TextureEntry;
import io.flutter.view.TextureRegistry.SurfaceTextureEntry;
import io.flutter.view.TextureRegistry.SurfaceProducer;
// TODO: implement SurfaceProducer.Callback.onSurfaceCreated/onSurfaceDestroyed https://github.com/flutter/engine/pull/53280/files#diff-5029b9afc856679672880958cdebb729d04892b7ec8c80ebd649ef55fff744f3

/** FvpPlugin */
public class FvpPlugin implements FlutterPlugin, MethodCallHandler {
Expand Down Expand Up @@ -71,23 +70,45 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
final boolean tunnel = (boolean)call.argument("tunnel");
TextureEntry te = null;
Surface surface = null;
if (impeller) {
SurfaceProducer sp = texRegistry.createSurfaceProducer();
final SurfaceProducer sp = impeller ? texRegistry.createSurfaceProducer() : null;
if (sp != null) {
sp.setSize(width, height);
surface = sp.getSurface();
te = sp;
} else {
SurfaceTextureEntry ste = texRegistry.createSurfaceTexture();
SurfaceTexture tex = ste.surfaceTexture();
tex.setDefaultBufferSize(width, height); // TODO: size from player. rotate, fullscreen change?
surface = new Surface(tex); // TODO: when to release
tex.setDefaultBufferSize(width, height);
surface = new Surface(tex);
te = ste;
}
long texId = te.id();
final long texId = te.id();
nativeSetSurface(handle, texId, surface, width, height, tunnel);
textures.put(texId, te);
surfaces.put(texId, surface);
result.success(texId);
if (sp != null) { // FIXME: requires 3.24. how to build conditionally?
// 3.24: https://docs.flutter.dev/release/breaking-changes/android-surface-plugins
sp.setCallback(
new TextureRegistry.SurfaceProducer.Callback() {
@Override
public void onSurfaceCreated() {
Log.d("FvpPlugin", "SurfaceProducer.onSurfaceCreated for textureId " + texId);
final Surface newSurface = sp.getSurface();
surfaces.put(texId, newSurface);
// will do nothing if same surface
nativeSetSurface(handle, texId, newSurface, width, height, tunnel);
}

@Override
public void onSurfaceDestroyed() {
Log.d("FvpPlugin", "SurfaceProducer.onSurfaceDestroyed for textureId " + texId);
textures.remove(texId);
nativeSetSurface(handle, texId, null, 0, 0, tunnel);
}
}
);
}
} else if (call.method.equals("ReleaseRT")) {
final int texId = call.argument("texture"); // 32bit int, 0, 1, 2 .... but SurfaceTexture.id() is long
final long texId64 = texId; // MUST cast texId to long, otherwise remove() error
Expand All @@ -99,10 +120,12 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
te.release();
}
if (textures.remove(texId64) == null) {
Log.w("FvpPlugin", "onMethodCall: ReleaseRT texture not found for " + texId);
}
if (surfaces.remove(texId64) == null) {
Log.w("FvpPlugin", "onMethodCall: ReleaseRT surface not found for " + texId);
}
Log.w("FvpPlugin", "onMethodCall: ReleaseRT texId: " + texId + ", surfaces: " + surfaces.size() + " textures: " + textures.size());
Log.i("FvpPlugin", "onMethodCall: ReleaseRT texId: " + texId + ", surfaces: " + surfaces.size() + " textures: " + textures.size());
result.success(null);
} else {
result.notImplemented();
Expand Down

0 comments on commit e67d3b7

Please sign in to comment.