mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-01 12:46:12 +00:00
a/android: Monitor whether MonadoView is still being used by native code.
This commit is contained in:
parent
6f989f5451
commit
66d6281a7f
|
@ -27,12 +27,27 @@ using wrap::android::view::SurfaceHolder;
|
|||
|
||||
struct android_custom_surface
|
||||
{
|
||||
Activity activity;
|
||||
jni::Class monadoViewClass;
|
||||
jni::Object monadoView;
|
||||
jni::method_t waitGetSurfaceHolderMethod;
|
||||
~android_custom_surface();
|
||||
Activity activity{};
|
||||
jni::Class monadoViewClass{};
|
||||
jni::Object monadoView{};
|
||||
jni::method_t waitGetSurfaceHolderMethod = nullptr;
|
||||
jni::method_t markAsDiscardedMethod = nullptr;
|
||||
};
|
||||
|
||||
android_custom_surface::~android_custom_surface()
|
||||
{
|
||||
if (!monadoView.isNull() && markAsDiscardedMethod != nullptr) {
|
||||
try {
|
||||
monadoView.call<void>(markAsDiscardedMethod);
|
||||
} catch (std::exception const &e) {
|
||||
U_LOG_E(
|
||||
"Failure while marking MonadoView as discarded: %s",
|
||||
e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto FULLY_QUALIFIED_CLASSNAME =
|
||||
"org.freedesktop.monado.auxiliary.MonadoView";
|
||||
|
||||
|
@ -89,6 +104,8 @@ android_custom_surface_async_start(struct _JavaVM *vm, void *activity)
|
|||
ret->monadoViewClass.getMethod(
|
||||
"waitGetSurfaceHolder",
|
||||
"(I)Landroid/view/SurfaceHolder;");
|
||||
ret->markAsDiscardedMethod = ret->monadoViewClass.getMethod(
|
||||
"markAsDiscardedByNative", "()V;");
|
||||
|
||||
attachToActivity = ret->monadoViewClass.getStaticMethod(
|
||||
"attachToActivity",
|
||||
|
|
|
@ -55,7 +55,8 @@ android_custom_surface_async_start(struct _JavaVM *vm, void *activity);
|
|||
* Destroy the native handle for the custom surface.
|
||||
*
|
||||
* Depending on the state, this may not necessarily destroy the underlying
|
||||
* surface, if other references exist.
|
||||
* surface, if other references exist. However, a flag will be set to indicate
|
||||
* that native code is done using it.
|
||||
*
|
||||
* @param ptr_custom_surface Pointer to the opaque pointer: will be set to NULL.
|
||||
*
|
||||
|
|
|
@ -43,13 +43,18 @@ public class MonadoView extends SurfaceView implements SurfaceHolder.Callback, S
|
|||
|
||||
/// Guards currentSurfaceHolder
|
||||
private final Object currentSurfaceHolderSync = new Object();
|
||||
/// Guards the usedByNativeCode flag
|
||||
private final Object usedByNativeCodeSync = new Object();
|
||||
private final Method viewSetSysUiVis;
|
||||
|
||||
public int width = -1;
|
||||
public int height = -1;
|
||||
public int format = -1;
|
||||
|
||||
/// Guarded by currentSurfaceHolderSync
|
||||
private SurfaceHolder currentSurfaceHolder = null;
|
||||
/// Guarded by usedByNativeCodeSync
|
||||
private boolean usedByNativeCode = false;
|
||||
|
||||
private MonadoView(Activity activity) {
|
||||
super(activity);
|
||||
|
@ -124,9 +129,34 @@ public class MonadoView extends SurfaceView implements SurfaceHolder.Callback, S
|
|||
}
|
||||
}
|
||||
}
|
||||
if (ret != null) {
|
||||
synchronized (usedByNativeCodeSync) {
|
||||
usedByNativeCode = true;
|
||||
usedByNativeCodeSync.notifyAll();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the flag and notify those waiting on it, to indicate that native code is done with
|
||||
* this object.
|
||||
* <p>
|
||||
* Called by native code!
|
||||
*/
|
||||
@Keep
|
||||
public void markAsDiscardedByNative() {
|
||||
|
||||
synchronized (usedByNativeCodeSync) {
|
||||
if (!usedByNativeCode) {
|
||||
Log.w(TAG, "This should not have happened: Discarding by native code, but not marked as used!");
|
||||
}
|
||||
usedByNativeCode = false;
|
||||
usedByNativeCodeSync.notifyAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean makeFullscreen() {
|
||||
if (activity == null) {
|
||||
return false;
|
||||
|
@ -190,11 +220,26 @@ public class MonadoView extends SurfaceView implements SurfaceHolder.Callback, S
|
|||
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
|
||||
//! @todo this function should block until the surface is no longer used in the native code.
|
||||
Log.i(TAG, "surfaceDestroyed: Lost our surface.");
|
||||
boolean lost = false;
|
||||
synchronized (currentSurfaceHolderSync) {
|
||||
if (surfaceHolder == currentSurfaceHolder) {
|
||||
currentSurfaceHolder = null;
|
||||
lost = true;
|
||||
}
|
||||
}
|
||||
if (lost) {
|
||||
//! @todo this function should notify native code that the surface is gone.
|
||||
try {
|
||||
synchronized (usedByNativeCodeSync) {
|
||||
while (usedByNativeCode) {
|
||||
usedByNativeCodeSync.wait();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
Log.i(TAG,
|
||||
"Interrupted in surfaceDestroyed while waiting for native code to finish up: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue