GL: Request OpenGL ES 3.0 context on API 29+, with fallback to 2.0.
Despite GL 3.0 not being required on API 29+, it is experimentally determined to always be supported on our testing devices, on API 29+. That said, still fall back to OpenGL 2.0 if 3.0 is not supported, just in case. PiperOrigin-RevId: 590569772
This commit is contained in:
parent
2fa5430417
commit
a15dfd75be
@ -366,11 +366,23 @@ public final class GlUtil {
|
||||
return eglSurface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link EGL14#EGL_CONTEXT_CLIENT_VERSION} of the current context.
|
||||
*
|
||||
* <p>Returns {@code 0} if no {@link EGLContext} {@linkplain #createFocusedPlaceholderEglSurface
|
||||
* is focused}.
|
||||
*/
|
||||
@RequiresApi(17)
|
||||
public static long getContextMajorVersion() throws GlException {
|
||||
return Api17.getContextMajorVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a newly created sync object and inserts it into the GL command stream.
|
||||
*
|
||||
* <p>Returns {@code 0} if the operation failed or the {@link EGLContext} version is less than
|
||||
* 3.0.
|
||||
* <p>Returns {@code 0} if the operation failed, no {@link EGLContext} {@linkplain
|
||||
* #createFocusedPlaceholderEglSurface is focused}, or the focused {@link EGLContext} version is
|
||||
* less than 3.0.
|
||||
*/
|
||||
@RequiresApi(17)
|
||||
public static long createGlSyncFence() throws GlException {
|
||||
|
@ -19,6 +19,7 @@ import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static androidx.media3.common.util.Assertions.checkState;
|
||||
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
||||
import static androidx.media3.common.util.Util.SDK_INT;
|
||||
import static androidx.media3.effect.DebugTraceUtil.EVENT_VFP_RECEIVE_END_OF_INPUT;
|
||||
import static androidx.media3.effect.DebugTraceUtil.EVENT_VFP_REGISTER_NEW_INPUT_STREAM;
|
||||
import static androidx.media3.effect.DebugTraceUtil.EVENT_VFP_SIGNAL_ENDED;
|
||||
@ -637,18 +638,20 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
ColorInfo.isTransferHdr(outputColorInfo)
|
||||
? GlUtil.EGL_CONFIG_ATTRIBUTES_RGBA_1010102
|
||||
: GlUtil.EGL_CONFIG_ATTRIBUTES_RGBA_8888;
|
||||
int openGlVersion =
|
||||
ColorInfo.isTransferHdr(inputColorInfo) || ColorInfo.isTransferHdr(outputColorInfo) ? 3 : 2;
|
||||
EGLContext eglContext =
|
||||
glObjectsProvider.createEglContext(eglDisplay, openGlVersion, configAttributes);
|
||||
glObjectsProvider.createFocusedPlaceholderEglSurface(eglContext, eglDisplay);
|
||||
createFocusedEglContextWithFallback(glObjectsProvider, eglDisplay, configAttributes);
|
||||
if ((ColorInfo.isTransferHdr(inputColorInfo) || ColorInfo.isTransferHdr(outputColorInfo))
|
||||
&& GlUtil.getContextMajorVersion() != 3) {
|
||||
throw new VideoFrameProcessingException(
|
||||
"OpenGL ES 3.0 context support is required for HDR input or output.");
|
||||
}
|
||||
|
||||
// Not renderFramesAutomatically means outputting to a display surface. HDR display surfaces
|
||||
// require the BT2020 PQ GL extension.
|
||||
if (!renderFramesAutomatically && ColorInfo.isTransferHdr(outputColorInfo)) {
|
||||
// Display hardware supports PQ only.
|
||||
checkArgument(outputColorInfo.colorTransfer == C.COLOR_TRANSFER_ST2084);
|
||||
if (Util.SDK_INT < 33 || !GlUtil.isBt2020PqExtensionSupported()) {
|
||||
if (SDK_INT < 33 || !GlUtil.isBt2020PqExtensionSupported()) {
|
||||
GlUtil.destroyEglContext(eglDisplay, eglContext);
|
||||
// On API<33, the system cannot display PQ content correctly regardless of whether BT2020 PQ
|
||||
// GL extension is supported.
|
||||
@ -882,6 +885,43 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates an OpenGL ES 3.0 context if possible, and an OpenGL ES 2.0 context otherwise. */
|
||||
private static EGLContext createFocusedEglContextWithFallback(
|
||||
GlObjectsProvider glObjectsProvider, EGLDisplay eglDisplay, int[] configAttributes)
|
||||
throws GlUtil.GlException {
|
||||
if (SDK_INT < 29) {
|
||||
return createFocusedEglContext(
|
||||
glObjectsProvider, eglDisplay, /* openGlVersion= */ 2, configAttributes);
|
||||
}
|
||||
|
||||
try {
|
||||
return createFocusedEglContext(
|
||||
glObjectsProvider, eglDisplay, /* openGlVersion= */ 3, configAttributes);
|
||||
} catch (GlUtil.GlException e) {
|
||||
return createFocusedEglContext(
|
||||
glObjectsProvider, eglDisplay, /* openGlVersion= */ 2, configAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link EGLContext} and focus it using a {@linkplain
|
||||
* GlObjectsProvider#createFocusedPlaceholderEglSurface placeholder EGL Surface}.
|
||||
*/
|
||||
private static EGLContext createFocusedEglContext(
|
||||
GlObjectsProvider glObjectsProvider,
|
||||
EGLDisplay eglDisplay,
|
||||
int openGlVersion,
|
||||
int[] configAttributes)
|
||||
throws GlUtil.GlException {
|
||||
EGLContext eglContext =
|
||||
glObjectsProvider.createEglContext(eglDisplay, openGlVersion, configAttributes);
|
||||
// Some OpenGL ES 3.0 contexts returned from createEglContext may throw EGL_BAD_MATCH when being
|
||||
// used to createFocusedPlaceHolderEglSurface, despite GL documentation suggesting the contexts,
|
||||
// if successfully created, are valid. Check early whether the context is really valid.
|
||||
glObjectsProvider.createFocusedPlaceholderEglSurface(eglContext, eglDisplay);
|
||||
return eglContext;
|
||||
}
|
||||
|
||||
private static final class InputStreamInfo {
|
||||
public final @InputType int inputType;
|
||||
public final List<Effect> effects;
|
||||
|
@ -48,6 +48,7 @@ import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@ -268,14 +269,16 @@ public final class HdrEditingTest {
|
||||
assertThat(isToneMappingFallbackApplied.get()).isTrue();
|
||||
assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR);
|
||||
} catch (ExportException exception) {
|
||||
if (exception.getCause() != null
|
||||
&& (Objects.equals(
|
||||
exception.getCause().getMessage(),
|
||||
"Decoding HDR is not supported on this device.")
|
||||
|| Objects.equals(
|
||||
exception.getCause().getMessage(), "Device lacks YUV extension support."))) {
|
||||
if (exception.getCause() != null) {
|
||||
@Nullable String message = exception.getCause().getMessage();
|
||||
if (message != null
|
||||
&& (Objects.equals(message, "Decoding HDR is not supported on this device.")
|
||||
|| message.contains(
|
||||
"OpenGL ES 3.0 context support is required for HDR input or output.")
|
||||
|| Objects.equals(message, "Device lacks YUV extension support."))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
@ -330,14 +333,16 @@ public final class HdrEditingTest {
|
||||
assertThat(isToneMappingFallbackApplied.get()).isTrue();
|
||||
assertFileHasColorTransfer(context, exportTestResult.filePath, C.COLOR_TRANSFER_SDR);
|
||||
} catch (ExportException exception) {
|
||||
if (exception.getCause() != null
|
||||
&& (Objects.equals(
|
||||
exception.getCause().getMessage(),
|
||||
"Decoding HDR is not supported on this device.")
|
||||
|| Objects.equals(
|
||||
exception.getCause().getMessage(), "Device lacks YUV extension support."))) {
|
||||
if (exception.getCause() != null) {
|
||||
@Nullable String message = exception.getCause().getMessage();
|
||||
if (message != null
|
||||
&& (Objects.equals(message, "Decoding HDR is not supported on this device.")
|
||||
|| message.contains(
|
||||
"OpenGL ES 3.0 context support is required for HDR input or output.")
|
||||
|| Objects.equals(message, "Device lacks YUV extension support."))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user