Loading core/java/android/view/Surface.java +11 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ public class Surface implements Parcelable { private static native long nativeGetNextFrameNumber(long nativeObject); private static native int nativeSetScalingMode(long nativeObject, int scalingMode); private static native void nativeSetBuffersTransform(long nativeObject, long transform); private static native int nativeForceScopedDisconnect(long nativeObject); public static final Parcelable.Creator<Surface> CREATOR = new Parcelable.Creator<Surface>() { Loading Loading @@ -550,6 +551,16 @@ public class Surface implements Parcelable { } } void forceScopedDisconnect() { synchronized (mLock) { checkNotReleasedLocked(); int err = nativeForceScopedDisconnect(mNativeObject); if (err != 0) { throw new RuntimeException("Failed to disconnect Surface instance (bad object?)"); } } } /** * Returns whether or not this Surface is backed by a single-buffered SurfaceTexture * @hide Loading core/java/android/view/SurfaceView.java +12 −0 Original line number Diff line number Diff line Loading @@ -587,6 +587,18 @@ public class SurfaceView extends View { for (SurfaceHolder.Callback c : callbacks) { c.surfaceDestroyed(mSurfaceHolder); } // Since Android N the same surface may be reused and given to us // again by the system server at a later point. However // as we didn't do this in previous releases, clients weren't // necessarily required to clean up properly in // surfaceDestroyed. This leads to problems for example when // clients don't destroy their EGL context, and try // and create a new one on the same surface following reuse. // Since there is no valid use of the surface in-between // surfaceDestroyed and surfaceCreated, we force a disconnect, // so the next connect will always work if we end up reusing // the surface. mSurface.forceScopedDisconnect(); } } Loading core/jni/android_view_Surface.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -487,6 +487,11 @@ static jint nativeSetScalingMode(JNIEnv *env, jclass clazz, jlong nativeObject, return surface->setScalingMode(scalingMode); } static jint nativeForceScopedDisconnect(JNIEnv *env, jclass clazz, jlong nativeObject) { Surface* surface = reinterpret_cast<Surface*>(nativeObject); return surface->disconnect(-1, IGraphicBufferProducer::DisconnectMode::AllLocal); } namespace uirenderer { using namespace android::uirenderer::renderthread; Loading Loading @@ -564,6 +569,7 @@ static const JNINativeMethod gSurfaceMethods[] = { {"nativeGetHeight", "(J)I", (void*)nativeGetHeight }, {"nativeGetNextFrameNumber", "(J)J", (void*)nativeGetNextFrameNumber }, {"nativeSetScalingMode", "(JI)I", (void*)nativeSetScalingMode }, {"nativeForceScopedDisconnect", "(J)I", (void*)nativeForceScopedDisconnect}, // HWUI context {"nHwuiCreate", "(JJ)J", (void*) hwui::create }, Loading Loading
core/java/android/view/Surface.java +11 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ public class Surface implements Parcelable { private static native long nativeGetNextFrameNumber(long nativeObject); private static native int nativeSetScalingMode(long nativeObject, int scalingMode); private static native void nativeSetBuffersTransform(long nativeObject, long transform); private static native int nativeForceScopedDisconnect(long nativeObject); public static final Parcelable.Creator<Surface> CREATOR = new Parcelable.Creator<Surface>() { Loading Loading @@ -550,6 +551,16 @@ public class Surface implements Parcelable { } } void forceScopedDisconnect() { synchronized (mLock) { checkNotReleasedLocked(); int err = nativeForceScopedDisconnect(mNativeObject); if (err != 0) { throw new RuntimeException("Failed to disconnect Surface instance (bad object?)"); } } } /** * Returns whether or not this Surface is backed by a single-buffered SurfaceTexture * @hide Loading
core/java/android/view/SurfaceView.java +12 −0 Original line number Diff line number Diff line Loading @@ -587,6 +587,18 @@ public class SurfaceView extends View { for (SurfaceHolder.Callback c : callbacks) { c.surfaceDestroyed(mSurfaceHolder); } // Since Android N the same surface may be reused and given to us // again by the system server at a later point. However // as we didn't do this in previous releases, clients weren't // necessarily required to clean up properly in // surfaceDestroyed. This leads to problems for example when // clients don't destroy their EGL context, and try // and create a new one on the same surface following reuse. // Since there is no valid use of the surface in-between // surfaceDestroyed and surfaceCreated, we force a disconnect, // so the next connect will always work if we end up reusing // the surface. mSurface.forceScopedDisconnect(); } } Loading
core/jni/android_view_Surface.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -487,6 +487,11 @@ static jint nativeSetScalingMode(JNIEnv *env, jclass clazz, jlong nativeObject, return surface->setScalingMode(scalingMode); } static jint nativeForceScopedDisconnect(JNIEnv *env, jclass clazz, jlong nativeObject) { Surface* surface = reinterpret_cast<Surface*>(nativeObject); return surface->disconnect(-1, IGraphicBufferProducer::DisconnectMode::AllLocal); } namespace uirenderer { using namespace android::uirenderer::renderthread; Loading Loading @@ -564,6 +569,7 @@ static const JNINativeMethod gSurfaceMethods[] = { {"nativeGetHeight", "(J)I", (void*)nativeGetHeight }, {"nativeGetNextFrameNumber", "(J)J", (void*)nativeGetNextFrameNumber }, {"nativeSetScalingMode", "(JI)I", (void*)nativeSetScalingMode }, {"nativeForceScopedDisconnect", "(J)I", (void*)nativeForceScopedDisconnect}, // HWUI context {"nHwuiCreate", "(JJ)J", (void*) hwui::create }, Loading