diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/GlUtil.java b/library/common/src/main/java/com/google/android/exoplayer2/util/GlUtil.java index b416beee33..4620b912d0 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/util/GlUtil.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/GlUtil.java @@ -213,6 +213,39 @@ public final class GlUtil { EGL_WINDOW_SURFACE_ATTRIBUTES_BT2020_PQ); } + /** + * Creates a new {@link EGLSurface} wrapping a pixel buffer. + * + * @param eglDisplay The {@link EGLDisplay} to attach the surface to. + * @param width The width of the pixel buffer. + * @param height The height of the pixel buffer. + */ + @RequiresApi(17) + private static EGLSurface createPbufferSurface(EGLDisplay eglDisplay, int width, int height) { + int[] pbufferAttributes = + new int[] { + EGL14.EGL_WIDTH, width, + EGL14.EGL_HEIGHT, height, + EGL14.EGL_NONE + }; + return Api17.createEglPbufferSurface( + eglDisplay, EGL_CONFIG_ATTRIBUTES_RGBA_8888, pbufferAttributes); + } + + /** + * Returns a placeholder {@link EGLSurface} to use when reading and writing to the surface is not + * required. + * + * @param eglDisplay The {@link EGLDisplay} to attach the surface to. + * @return {@link EGL14#EGL_NO_SURFACE} if supported and a 1x1 pixel buffer surface otherwise. + */ + @RequiresApi(17) + public static EGLSurface createPlaceholderEglSurface(EGLDisplay eglDisplay) { + return isSurfacelessContextExtensionSupported() + ? EGL14.EGL_NO_SURFACE + : createPbufferSurface(eglDisplay, /* width= */ 1, /* height= */ 1); + } + /** * Creates and focuses a new {@link EGLSurface} wrapping a 1x1 pixel buffer. * @@ -221,15 +254,7 @@ public final class GlUtil { */ @RequiresApi(17) public static void focusPlaceholderEglSurface(EGLContext eglContext, EGLDisplay eglDisplay) { - int[] pbufferAttributes = - new int[] { - EGL14.EGL_WIDTH, /* width= */ 1, - EGL14.EGL_HEIGHT, /* height= */ 1, - EGL14.EGL_NONE - }; - EGLSurface eglSurface = - Api17.createEglPbufferSurface( - eglDisplay, EGL_CONFIG_ATTRIBUTES_RGBA_8888, pbufferAttributes); + EGLSurface eglSurface = createPbufferSurface(eglDisplay, /* width= */ 1, /* height= */ 1); focusEglSurface(eglDisplay, eglContext, eglSurface, /* width= */ 1, /* height= */ 1); } diff --git a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/AdvancedFrameProcessorPixelTest.java b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/AdvancedFrameProcessorPixelTest.java index 554a282594..6f92811095 100644 --- a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/AdvancedFrameProcessorPixelTest.java +++ b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/AdvancedFrameProcessorPixelTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import android.graphics.Bitmap; import android.graphics.Matrix; -import android.graphics.SurfaceTexture; import android.opengl.EGLContext; import android.opengl.EGLDisplay; import android.opengl.EGLSurface; @@ -70,15 +69,13 @@ public final class AdvancedFrameProcessorPixelTest { Bitmap inputBitmap = BitmapTestUtil.readBitmap(ORIGINAL_PNG_ASSET_PATH); width = inputBitmap.getWidth(); height = inputBitmap.getHeight(); - // This surface is needed for focussing a render target, but the tests don't write output to it. - // The frame processor's output is written to a framebuffer instead. - EGLSurface eglSurface = - GlUtil.getEglSurface(eglDisplay, new SurfaceTexture(/* singleBufferMode= */ false)); - GlUtil.focusEglSurface(eglDisplay, eglContext, eglSurface, width, height); + EGLSurface placeholderEglSurface = GlUtil.createPlaceholderEglSurface(eglDisplay); + GlUtil.focusEglSurface(eglDisplay, eglContext, placeholderEglSurface, width, height); inputTexId = BitmapTestUtil.createGlTextureFromBitmap(inputBitmap); outputTexId = GlUtil.createTexture(width, height); int frameBuffer = GlUtil.createFboForTexture(outputTexId); - GlUtil.focusFramebuffer(eglDisplay, eglContext, eglSurface, frameBuffer, width, height); + GlUtil.focusFramebuffer( + eglDisplay, eglContext, placeholderEglSurface, frameBuffer, width, height); } @After diff --git a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/PresentationFrameProcessorPixelTest.java b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/PresentationFrameProcessorPixelTest.java index a8b85d92eb..0d75f4cb72 100644 --- a/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/PresentationFrameProcessorPixelTest.java +++ b/library/transformer/src/androidTest/java/com/google/android/exoplayer2/transformer/PresentationFrameProcessorPixelTest.java @@ -17,16 +17,15 @@ package com.google.android.exoplayer2.transformer; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static com.google.android.exoplayer2.transformer.BitmapTestUtil.MAXIMUM_AVERAGE_PIXEL_ABSOLUTE_DIFFERENCE; +import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.common.truth.Truth.assertThat; import android.graphics.Bitmap; -import android.graphics.SurfaceTexture; import android.opengl.EGLContext; import android.opengl.EGLDisplay; import android.opengl.EGLSurface; import android.util.Size; import androidx.test.ext.junit.runners.AndroidJUnit4; -import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.GlUtil; import java.io.IOException; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @@ -71,7 +70,7 @@ public final class PresentationFrameProcessorPixelTest { private final EGLDisplay eglDisplay = GlUtil.createEglDisplay(); private final EGLContext eglContext = GlUtil.createEglContext(eglDisplay); private @MonotonicNonNull GlFrameProcessor presentationFrameProcessor; - private @MonotonicNonNull EGLSurface eglSurface; + private @MonotonicNonNull EGLSurface placeholderEglSurface; private int inputTexId; private int outputTexId; private int inputWidth; @@ -82,11 +81,8 @@ public final class PresentationFrameProcessorPixelTest { Bitmap inputBitmap = BitmapTestUtil.readBitmap(ORIGINAL_PNG_ASSET_PATH); inputWidth = inputBitmap.getWidth(); inputHeight = inputBitmap.getHeight(); - // This surface is needed for focussing a render target, but the tests don't write output to it. - // The frame processor's output is written to a framebuffer instead. - eglSurface = - GlUtil.getEglSurface(eglDisplay, new SurfaceTexture(/* singleBufferMode= */ false)); - GlUtil.focusEglSurface(eglDisplay, eglContext, eglSurface, inputWidth, inputHeight); + placeholderEglSurface = GlUtil.createPlaceholderEglSurface(eglDisplay); + GlUtil.focusEglSurface(eglDisplay, eglContext, placeholderEglSurface, inputWidth, inputHeight); inputTexId = BitmapTestUtil.createGlTextureFromBitmap(inputBitmap); } @@ -356,7 +352,7 @@ public final class PresentationFrameProcessorPixelTest { GlUtil.focusFramebuffer( eglDisplay, eglContext, - Assertions.checkNotNull(eglSurface), + checkNotNull(placeholderEglSurface), frameBuffer, outputWidth, outputHeight);