The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

a/android: Monitor whether MonadoView is still being used by native code.

+69 -6
+21 -4
src/xrt/auxiliary/android/android_custom_surface.cpp
··· 27 27 28 28 struct android_custom_surface 29 29 { 30 - Activity activity; 31 - jni::Class monadoViewClass; 32 - jni::Object monadoView; 33 - jni::method_t waitGetSurfaceHolderMethod; 30 + ~android_custom_surface(); 31 + Activity activity{}; 32 + jni::Class monadoViewClass{}; 33 + jni::Object monadoView{}; 34 + jni::method_t waitGetSurfaceHolderMethod = nullptr; 35 + jni::method_t markAsDiscardedMethod = nullptr; 34 36 }; 37 + 38 + android_custom_surface::~android_custom_surface() 39 + { 40 + if (!monadoView.isNull() && markAsDiscardedMethod != nullptr) { 41 + try { 42 + monadoView.call<void>(markAsDiscardedMethod); 43 + } catch (std::exception const &e) { 44 + U_LOG_E( 45 + "Failure while marking MonadoView as discarded: %s", 46 + e.what()); 47 + } 48 + } 49 + } 35 50 36 51 constexpr auto FULLY_QUALIFIED_CLASSNAME = 37 52 "org.freedesktop.monado.auxiliary.MonadoView"; ··· 89 104 ret->monadoViewClass.getMethod( 90 105 "waitGetSurfaceHolder", 91 106 "(I)Landroid/view/SurfaceHolder;"); 107 + ret->markAsDiscardedMethod = ret->monadoViewClass.getMethod( 108 + "markAsDiscardedByNative", "()V;"); 92 109 93 110 attachToActivity = ret->monadoViewClass.getStaticMethod( 94 111 "attachToActivity",
+2 -1
src/xrt/auxiliary/android/android_custom_surface.h
··· 55 55 * Destroy the native handle for the custom surface. 56 56 * 57 57 * Depending on the state, this may not necessarily destroy the underlying 58 - * surface, if other references exist. 58 + * surface, if other references exist. However, a flag will be set to indicate 59 + * that native code is done using it. 59 60 * 60 61 * @param ptr_custom_surface Pointer to the opaque pointer: will be set to NULL. 61 62 *
+46 -1
src/xrt/auxiliary/android/src/main/java/org/freedesktop/monado/auxiliary/MonadoView.java
··· 43 43 44 44 /// Guards currentSurfaceHolder 45 45 private final Object currentSurfaceHolderSync = new Object(); 46 + /// Guards the usedByNativeCode flag 47 + private final Object usedByNativeCodeSync = new Object(); 46 48 private final Method viewSetSysUiVis; 49 + 47 50 public int width = -1; 48 51 public int height = -1; 49 52 public int format = -1; 50 53 51 54 /// Guarded by currentSurfaceHolderSync 52 55 private SurfaceHolder currentSurfaceHolder = null; 56 + /// Guarded by usedByNativeCodeSync 57 + private boolean usedByNativeCode = false; 53 58 54 59 private MonadoView(Activity activity) { 55 60 super(activity); ··· 124 129 } 125 130 } 126 131 } 132 + if (ret != null) { 133 + synchronized (usedByNativeCodeSync) { 134 + usedByNativeCode = true; 135 + usedByNativeCodeSync.notifyAll(); 136 + } 137 + } 127 138 return ret; 128 139 } 129 140 141 + /** 142 + * Change the flag and notify those waiting on it, to indicate that native code is done with 143 + * this object. 144 + * <p> 145 + * Called by native code! 146 + */ 147 + @Keep 148 + public void markAsDiscardedByNative() { 149 + 150 + synchronized (usedByNativeCodeSync) { 151 + if (!usedByNativeCode) { 152 + Log.w(TAG, "This should not have happened: Discarding by native code, but not marked as used!"); 153 + } 154 + usedByNativeCode = false; 155 + usedByNativeCodeSync.notifyAll(); 156 + } 157 + 158 + } 159 + 130 160 private boolean makeFullscreen() { 131 161 if (activity == null) { 132 162 return false; ··· 190 220 191 221 @Override 192 222 public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) { 193 - //! @todo this function should block until the surface is no longer used in the native code. 194 223 Log.i(TAG, "surfaceDestroyed: Lost our surface."); 224 + boolean lost = false; 195 225 synchronized (currentSurfaceHolderSync) { 196 226 if (surfaceHolder == currentSurfaceHolder) { 197 227 currentSurfaceHolder = null; 228 + lost = true; 229 + } 230 + } 231 + if (lost) { 232 + //! @todo this function should notify native code that the surface is gone. 233 + try { 234 + synchronized (usedByNativeCodeSync) { 235 + while (usedByNativeCode) { 236 + usedByNativeCodeSync.wait(); 237 + } 238 + } 239 + } catch (InterruptedException e) { 240 + e.printStackTrace(); 241 + Log.i(TAG, 242 + "Interrupted in surfaceDestroyed while waiting for native code to finish up: " + e.toString()); 198 243 } 199 244 } 200 245 }