Commit 47d63504 by claincly Committed by microkatz

Destroy eglSurface in FrameProcessor

Previously, FrameProcessor never had the usecase in which the output surface
is replaced, while previewing introduced this usecase.

When switching output surfaces, we need to destroy the EGL Surface linked to the
surface that is being swapped out, because an EGL surface is linked to the EGL
display (which is not destroyed even when releasing FrameProcessor).

A GL exception will be thrown in the following scenario if we don't destroy the
EGL surface:

1. Creates a Surface, the surface is identified by address 0x11
2. Sets Surface(0x11) on FrameProcessor. Eventually an EGL surface is created
  to wrap Surface(0x11)
3. Release FrameProcess, this releases the EGL context
4. Instantiate a new FrameProcessor, sets Surface(0x11) as the output
5. When FrameProcessor creates an EGL surface to wrap Surface(0x11), GL throws
  an exception, becasue Surface(0x11) has previouly been connected to an EGL
  surface.

PiperOrigin-RevId: 489590072
parent b81cd082
...@@ -469,6 +469,16 @@ public final class GlUtil { ...@@ -469,6 +469,16 @@ public final class GlUtil {
} }
/** /**
* Destroys the {@link EGLSurface} identified by the provided {@link EGLDisplay} and {@link
* EGLSurface}.
*/
@RequiresApi(17)
public static void destroyEglSurface(
@Nullable EGLDisplay eglDisplay, @Nullable EGLSurface eglSurface) throws GlException {
Api17.destroyEglSurface(eglDisplay, eglSurface);
}
/**
* Allocates a FloatBuffer with the given data. * Allocates a FloatBuffer with the given data.
* *
* @param data Used to initialize the new buffer. * @param data Used to initialize the new buffer.
...@@ -734,6 +744,16 @@ public final class GlUtil { ...@@ -734,6 +744,16 @@ public final class GlUtil {
} }
@DoNotInline @DoNotInline
public static void destroyEglSurface(
@Nullable EGLDisplay eglDisplay, @Nullable EGLSurface eglSurface) throws GlException {
if (eglDisplay == null || eglSurface == null) {
return;
}
EGL14.eglDestroySurface(eglDisplay, eglSurface);
checkEglException("Error destroying surface");
}
@DoNotInline
private static EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] attributes) private static EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] attributes)
throws GlException { throws GlException {
EGLConfig[] eglConfigs = new EGLConfig[1]; EGLConfig[] eglConfigs = new EGLConfig[1];
......
...@@ -183,10 +183,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -183,10 +183,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
@WorkerThread @WorkerThread
public void release() throws FrameProcessingException { public synchronized void release() throws FrameProcessingException {
if (matrixTextureProcessor != null) { if (matrixTextureProcessor != null) {
matrixTextureProcessor.release(); matrixTextureProcessor.release();
} }
try {
GlUtil.destroyEglSurface(eglDisplay, outputEglSurface);
} catch (GlUtil.GlException e) {
throw new FrameProcessingException(e);
}
} }
@Override @Override
...@@ -226,6 +231,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -226,6 +231,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
if (outputSurfaceInfo != null if (outputSurfaceInfo != null
&& this.outputSurfaceInfo != null && this.outputSurfaceInfo != null
&& !this.outputSurfaceInfo.surface.equals(outputSurfaceInfo.surface)) { && !this.outputSurfaceInfo.surface.equals(outputSurfaceInfo.surface)) {
try {
GlUtil.destroyEglSurface(eglDisplay, outputEglSurface);
} catch (GlUtil.GlException e) {
frameProcessorListener.onFrameProcessingError(FrameProcessingException.from(e));
}
this.outputEglSurface = null; this.outputEglSurface = null;
} }
outputSizeOrRotationChanged = outputSizeOrRotationChanged =
...@@ -307,6 +317,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -307,6 +317,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
matrixTextureProcessor.release(); matrixTextureProcessor.release();
matrixTextureProcessor = null; matrixTextureProcessor = null;
} }
GlUtil.destroyEglSurface(eglDisplay, outputEglSurface);
outputEglSurface = null; outputEglSurface = null;
return false; return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment