From 0c4b48608128a3e6939005ba71d0907fbe2dfb38 Mon Sep 17 00:00:00 2001 From: tofunmi Date: Thu, 20 Apr 2023 12:24:54 +0100 Subject: [PATCH] Add context sharing capabilities to the default GlObjectsProvider Creates a way for apps to provide their EGLContext to DefaultVideoFrameProcessor, so that we can attach their context to the one we create. See [the EGL docs for more information about how contexts are shared in GL](https://registry.khronos.org/EGL/sdk/docs/man/html/eglCreateContext.xhtml) PiperOrigin-RevId: 525708652 --- .../media3/common/GlObjectsProvider.java | 7 +- .../androidx/media3/common/util/GlUtil.java | 16 ++-- .../effect/DefaultGlObjectsProvider.java | 80 +++++++++++++++++++ 3 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 libraries/effect/src/main/java/androidx/media3/effect/DefaultGlObjectsProvider.java diff --git a/libraries/common/src/main/java/androidx/media3/common/GlObjectsProvider.java b/libraries/common/src/main/java/androidx/media3/common/GlObjectsProvider.java index 8a4bd7fc6c..85efccaac9 100644 --- a/libraries/common/src/main/java/androidx/media3/common/GlObjectsProvider.java +++ b/libraries/common/src/main/java/androidx/media3/common/GlObjectsProvider.java @@ -31,16 +31,17 @@ import androidx.media3.common.util.UnstableApi; @UnstableApi public interface GlObjectsProvider { /** - * Provider for GL objects that configures a GL context with 8-bit RGB or 10-bit RGB attributes, - * and no depth buffer or render buffers. + * @deprecated Please use {@code DefaultGlObjectsProvider} in {@code androidx.media3.effect}. */ + @Deprecated GlObjectsProvider DEFAULT = new GlObjectsProvider() { @Override @RequiresApi(17) public EGLContext createEglContext( EGLDisplay eglDisplay, int openGlVersion, int[] configAttributes) throws GlException { - return GlUtil.createEglContext(eglDisplay, openGlVersion, configAttributes); + return GlUtil.createEglContext( + EGL14.EGL_NO_CONTEXT, eglDisplay, openGlVersion, configAttributes); } @Override diff --git a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java index c5b220e361..033ab30332 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/GlUtil.java @@ -249,12 +249,14 @@ public final class GlUtil { */ @RequiresApi(17) public static EGLContext createEglContext(EGLDisplay eglDisplay) throws GlException { - return createEglContext(eglDisplay, /* openGlVersion= */ 2, EGL_CONFIG_ATTRIBUTES_RGBA_8888); + return createEglContext( + EGL14.EGL_NO_CONTEXT, eglDisplay, /* openGlVersion= */ 2, EGL_CONFIG_ATTRIBUTES_RGBA_8888); } /** * Creates a new {@link EGLContext} for the specified {@link EGLDisplay}. * + * @param sharedContext The {@link EGLContext} with which to share data. * @param eglDisplay The {@link EGLDisplay} to create an {@link EGLContext} for. * @param openGlVersion The version of OpenGL ES to configure. Accepts either {@code 2}, for * OpenGL ES 2.0, or {@code 3}, for OpenGL ES 3.0. @@ -263,13 +265,16 @@ public final class GlUtil { */ @RequiresApi(17) public static EGLContext createEglContext( - EGLDisplay eglDisplay, @IntRange(from = 2, to = 3) int openGlVersion, int[] configAttributes) + EGLContext sharedContext, + EGLDisplay eglDisplay, + @IntRange(from = 2, to = 3) int openGlVersion, + int[] configAttributes) throws GlException { checkArgument( Arrays.equals(configAttributes, EGL_CONFIG_ATTRIBUTES_RGBA_8888) || Arrays.equals(configAttributes, EGL_CONFIG_ATTRIBUTES_RGBA_1010102)); checkArgument(openGlVersion == 2 || openGlVersion == 3); - return Api17.createEglContext(eglDisplay, openGlVersion, configAttributes); + return Api17.createEglContext(sharedContext, eglDisplay, openGlVersion, configAttributes); } /** @@ -691,13 +696,14 @@ public final class GlUtil { @DoNotInline public static EGLContext createEglContext( - EGLDisplay eglDisplay, int version, int[] configAttributes) throws GlException { + EGLContext sharedContext, EGLDisplay eglDisplay, int version, int[] configAttributes) + throws GlException { int[] contextAttributes = {EGL14.EGL_CONTEXT_CLIENT_VERSION, version, EGL14.EGL_NONE}; EGLContext eglContext = EGL14.eglCreateContext( eglDisplay, getEglConfig(eglDisplay, configAttributes), - EGL14.EGL_NO_CONTEXT, + sharedContext, contextAttributes, /* offset= */ 0); if (eglContext == null) { diff --git a/libraries/effect/src/main/java/androidx/media3/effect/DefaultGlObjectsProvider.java b/libraries/effect/src/main/java/androidx/media3/effect/DefaultGlObjectsProvider.java new file mode 100644 index 0000000000..c3bf13e797 --- /dev/null +++ b/libraries/effect/src/main/java/androidx/media3/effect/DefaultGlObjectsProvider.java @@ -0,0 +1,80 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.effect; + +import android.opengl.EGL14; +import android.opengl.EGLContext; +import android.opengl.EGLDisplay; +import android.opengl.EGLSurface; +import androidx.annotation.Nullable; +import androidx.media3.common.C; +import androidx.media3.common.GlObjectsProvider; +import androidx.media3.common.GlTextureInfo; +import androidx.media3.common.util.GlUtil; +import androidx.media3.common.util.UnstableApi; + +// TODO(b/261820382): Add tests for sharing context. +/** + * Implementation of {@link GlObjectsProvider} that configures an {@link EGLContext} to share data + * with a preexisting {@code sharedEglContext}. + * + *

The created {@link EGLContext} is configured with 8-bit RGB or 10-bit RGB attributes and no + * depth buffer or render buffers. + */ +@UnstableApi +public final class DefaultGlObjectsProvider implements GlObjectsProvider { + + private final EGLContext sharedEglContext; + + /** + * Creates an instance. + * + * @param sharedEglContext The {@link EGLContext} with which to share data. + */ + public DefaultGlObjectsProvider(@Nullable EGLContext sharedEglContext) { + this.sharedEglContext = sharedEglContext != null ? sharedEglContext : EGL14.EGL_NO_CONTEXT; + } + + @Override + public EGLContext createEglContext( + EGLDisplay eglDisplay, int openGlVersion, int[] configAttributes) throws GlUtil.GlException { + return GlUtil.createEglContext(sharedEglContext, eglDisplay, openGlVersion, configAttributes); + } + + @Override + public EGLSurface createEglSurface( + EGLDisplay eglDisplay, + Object surface, + @C.ColorTransfer int colorTransfer, + boolean isEncoderInputSurface) + throws GlUtil.GlException { + return GlUtil.createEglSurface(eglDisplay, surface, colorTransfer, isEncoderInputSurface); + } + + @Override + public EGLSurface createFocusedPlaceholderEglSurface( + EGLContext eglContext, EGLDisplay eglDisplay, int[] configAttributes) + throws GlUtil.GlException { + return GlUtil.createFocusedPlaceholderEglSurface(eglContext, eglDisplay, configAttributes); + } + + @Override + public GlTextureInfo createBuffersForTexture(int texId, int width, int height) + throws GlUtil.GlException { + int fboId = GlUtil.createFboForTexture(texId); + return new GlTextureInfo(texId, fboId, /* rboId= */ C.INDEX_UNSET, width, height); + } +}