/** * Calls {@link #destroy()} directly if the following requirements are met: * * <ul> * <li>An {@link GLAnimatorControl} is bound (see {@link #getAnimator()}) and running on another * thread. Here we pause the animation while issuing the destruction. * <li>Surface is not locked by another thread (considered anonymous). * </ul> * * <p>Otherwise destroy is being flagged to be called within the next call of display(). * * <p>This method is being used to avoid deadlock if destruction is desired by <i>other</i> * threads, e.g. the window manager. * * @see #defaultWindowDestroyNotifyOp() * @see #defaultDisplay() */ protected final void destroyAvoidAwareOfLocking() { final NativeSurface ns = getNativeSurface(); final GLAnimatorControl ctrl = helper.getAnimator(); // Is an animator thread perform rendering? if (helper.isAnimatorStartedOnOtherThread()) { // Pause animations before initiating safe destroy. final boolean isPaused = ctrl.pause(); destroy(); if (isPaused) { ctrl.resume(); } } else if (null != ns && ns.isSurfaceLockedByOtherThread()) { // Surface is locked by another thread. // Flag that destroy should be performed on the next // attempt to display. sendDestroy = true; // async, but avoiding deadlock } else { // Without an external thread animating or locking the // surface, we are safe. destroy(); } }