mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-19 21:28:50 +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
|
struct android_custom_surface
|
||||||
{
|
{
|
||||||
Activity activity;
|
~android_custom_surface();
|
||||||
jni::Class monadoViewClass;
|
Activity activity{};
|
||||||
jni::Object monadoView;
|
jni::Class monadoViewClass{};
|
||||||
jni::method_t waitGetSurfaceHolderMethod;
|
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 =
|
constexpr auto FULLY_QUALIFIED_CLASSNAME =
|
||||||
"org.freedesktop.monado.auxiliary.MonadoView";
|
"org.freedesktop.monado.auxiliary.MonadoView";
|
||||||
|
|
||||||
|
@ -89,6 +104,8 @@ android_custom_surface_async_start(struct _JavaVM *vm, void *activity)
|
||||||
ret->monadoViewClass.getMethod(
|
ret->monadoViewClass.getMethod(
|
||||||
"waitGetSurfaceHolder",
|
"waitGetSurfaceHolder",
|
||||||
"(I)Landroid/view/SurfaceHolder;");
|
"(I)Landroid/view/SurfaceHolder;");
|
||||||
|
ret->markAsDiscardedMethod = ret->monadoViewClass.getMethod(
|
||||||
|
"markAsDiscardedByNative", "()V;");
|
||||||
|
|
||||||
attachToActivity = ret->monadoViewClass.getStaticMethod(
|
attachToActivity = ret->monadoViewClass.getStaticMethod(
|
||||||
"attachToActivity",
|
"attachToActivity",
|
||||||
|
|
|
@ -55,7 +55,8 @@ android_custom_surface_async_start(struct _JavaVM *vm, void *activity);
|
||||||
* Destroy the native handle for the custom surface.
|
* Destroy the native handle for the custom surface.
|
||||||
*
|
*
|
||||||
* Depending on the state, this may not necessarily destroy the underlying
|
* 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.
|
* @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
|
/// Guards currentSurfaceHolder
|
||||||
private final Object currentSurfaceHolderSync = new Object();
|
private final Object currentSurfaceHolderSync = new Object();
|
||||||
|
/// Guards the usedByNativeCode flag
|
||||||
|
private final Object usedByNativeCodeSync = new Object();
|
||||||
private final Method viewSetSysUiVis;
|
private final Method viewSetSysUiVis;
|
||||||
|
|
||||||
public int width = -1;
|
public int width = -1;
|
||||||
public int height = -1;
|
public int height = -1;
|
||||||
public int format = -1;
|
public int format = -1;
|
||||||
|
|
||||||
/// Guarded by currentSurfaceHolderSync
|
/// Guarded by currentSurfaceHolderSync
|
||||||
private SurfaceHolder currentSurfaceHolder = null;
|
private SurfaceHolder currentSurfaceHolder = null;
|
||||||
|
/// Guarded by usedByNativeCodeSync
|
||||||
|
private boolean usedByNativeCode = false;
|
||||||
|
|
||||||
private MonadoView(Activity activity) {
|
private MonadoView(Activity activity) {
|
||||||
super(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;
|
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() {
|
private boolean makeFullscreen() {
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -190,11 +220,26 @@ public class MonadoView extends SurfaceView implements SurfaceHolder.Callback, S
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
|
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.");
|
Log.i(TAG, "surfaceDestroyed: Lost our surface.");
|
||||||
|
boolean lost = false;
|
||||||
synchronized (currentSurfaceHolderSync) {
|
synchronized (currentSurfaceHolderSync) {
|
||||||
if (surfaceHolder == currentSurfaceHolder) {
|
if (surfaceHolder == currentSurfaceHolder) {
|
||||||
currentSurfaceHolder = null;
|
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