In-line GlUtil.Api18 and VideoFrameReleaseHelper.DisplayHelperV16/17
Also put back a comment in DownloadTracker that is still relevant on API 19. Also deprecate PlaceholderSurface.newInstanceV17() in favour of just newInstance()
This commit is contained in:
parent
d327cb4795
commit
c0c1c315c5
@ -199,6 +199,8 @@ public class DownloadTracker {
|
||||
return;
|
||||
}
|
||||
|
||||
// The content is DRM protected. We need to acquire an offline license.
|
||||
|
||||
// TODO(internal b/163107948): Support cases where DrmInitData are not in the manifest.
|
||||
if (!hasNonNullWidevineSchemaData(format.drmInitData)) {
|
||||
Toast.makeText(context, R.string.download_start_error_offline_license, Toast.LENGTH_LONG)
|
||||
|
@ -180,7 +180,7 @@ public final class GlUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Api17.isExtensionSupported(EXTENSION_PROTECTED_CONTENT);
|
||||
return isExtensionSupported(EXTENSION_PROTECTED_CONTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,7 +191,7 @@ public final class GlUtil {
|
||||
* EGLContext)}.
|
||||
*/
|
||||
public static boolean isSurfacelessContextExtensionSupported() {
|
||||
return Api17.isExtensionSupported(EXTENSION_SURFACELESS_CONTEXT);
|
||||
return isExtensionSupported(EXTENSION_SURFACELESS_CONTEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -202,7 +202,7 @@ public final class GlUtil {
|
||||
*/
|
||||
public static boolean isYuvTargetExtensionSupported() {
|
||||
@Nullable String glExtensions;
|
||||
if (Util.areEqual(Api17.getCurrentContext(), EGL14.EGL_NO_CONTEXT)) {
|
||||
if (Util.areEqual(EGL14.eglGetCurrentContext(), EGL14.EGL_NO_CONTEXT)) {
|
||||
// Create a placeholder context and make it current to allow calling GLES20.glGetString().
|
||||
try {
|
||||
EGLDisplay eglDisplay = getDefaultEglDisplay();
|
||||
@ -222,12 +222,23 @@ public final class GlUtil {
|
||||
|
||||
/** Returns whether {@link #EXTENSION_COLORSPACE_BT2020_PQ} is supported. */
|
||||
public static boolean isBt2020PqExtensionSupported() {
|
||||
return Api17.isExtensionSupported(EXTENSION_COLORSPACE_BT2020_PQ);
|
||||
return isExtensionSupported(EXTENSION_COLORSPACE_BT2020_PQ);
|
||||
}
|
||||
|
||||
/** Returns an initialized default {@link EGLDisplay}. */
|
||||
public static EGLDisplay getDefaultEglDisplay() throws GlException {
|
||||
return Api17.getDefaultEglDisplay();
|
||||
EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
|
||||
checkGlException(!eglDisplay.equals(EGL14.EGL_NO_DISPLAY), "No EGL display.");
|
||||
checkGlException(
|
||||
EGL14.eglInitialize(
|
||||
eglDisplay,
|
||||
/* unusedMajor */ new int[1],
|
||||
/* majorOffset= */ 0,
|
||||
/* unusedMinor */ new int[1],
|
||||
/* minorOffset= */ 0),
|
||||
"Error in eglInitialize.");
|
||||
checkGlError();
|
||||
return eglDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -263,7 +274,23 @@ public final class GlUtil {
|
||||
Arrays.equals(configAttributes, EGL_CONFIG_ATTRIBUTES_RGBA_8888)
|
||||
|| Arrays.equals(configAttributes, EGL_CONFIG_ATTRIBUTES_RGBA_1010102));
|
||||
checkArgument(openGlVersion == 2 || openGlVersion == 3);
|
||||
return Api17.createEglContext(sharedContext, eglDisplay, openGlVersion, configAttributes);
|
||||
int[] contextAttributes = {EGL_CONTEXT_CLIENT_VERSION, openGlVersion, EGL14.EGL_NONE};
|
||||
EGLContext eglContext =
|
||||
EGL14.eglCreateContext(
|
||||
eglDisplay,
|
||||
getEglConfig(eglDisplay, configAttributes),
|
||||
sharedContext,
|
||||
contextAttributes,
|
||||
/* offset= */ 0);
|
||||
if (eglContext == null) {
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
throw new GlException(
|
||||
"eglCreateContext() failed to create a valid context. The device may not support EGL"
|
||||
+ " version "
|
||||
+ openGlVersion);
|
||||
}
|
||||
checkGlError();
|
||||
return eglContext;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -308,7 +335,15 @@ public final class GlUtil {
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported color transfer: " + colorTransfer);
|
||||
}
|
||||
return Api17.createEglSurface(eglDisplay, surface, configAttributes, windowAttributes);
|
||||
EGLSurface eglSurface =
|
||||
EGL14.eglCreateWindowSurface(
|
||||
eglDisplay,
|
||||
getEglConfig(eglDisplay, configAttributes),
|
||||
surface,
|
||||
windowAttributes,
|
||||
/* offset= */ 0);
|
||||
checkEglException("Error creating a new EGL surface");
|
||||
return eglSurface;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -328,7 +363,14 @@ public final class GlUtil {
|
||||
EGL14.EGL_HEIGHT, height,
|
||||
EGL14.EGL_NONE
|
||||
};
|
||||
return Api17.createEglPbufferSurface(eglDisplay, configAttributes, pbufferAttributes);
|
||||
EGLSurface eglSurface =
|
||||
EGL14.eglCreatePbufferSurface(
|
||||
eglDisplay,
|
||||
getEglConfig(eglDisplay, configAttributes),
|
||||
pbufferAttributes,
|
||||
/* offset= */ 0);
|
||||
checkEglException("Error creating a new EGL Pbuffer surface");
|
||||
return eglSurface;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -363,8 +405,15 @@ public final class GlUtil {
|
||||
* is focused}.
|
||||
*/
|
||||
public static long getContextMajorVersion() throws GlException {
|
||||
return Api17.getContextMajorVersion();
|
||||
}
|
||||
int[] currentEglContextVersion = new int[1];
|
||||
EGL14.eglQueryContext(
|
||||
EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY),
|
||||
EGL14.eglGetCurrentContext(),
|
||||
EGL_CONTEXT_CLIENT_VERSION,
|
||||
currentEglContextVersion,
|
||||
/* offset= */ 0);
|
||||
checkGlError();
|
||||
return currentEglContextVersion[0]; }
|
||||
|
||||
/**
|
||||
* Returns a newly created sync object and inserts it into the GL command stream.
|
||||
@ -374,8 +423,19 @@ public final class GlUtil {
|
||||
* less than 3.0.
|
||||
*/
|
||||
public static long createGlSyncFence() throws GlException {
|
||||
// If the context is an OpenGL 3.0 context, we must be running API 18 or later.
|
||||
return Api17.getContextMajorVersion() >= 3 ? Api18.createSyncFence() : 0;
|
||||
if (getContextMajorVersion() >= 3) {
|
||||
long syncObject = GLES30.glFenceSync(GLES30.GL_SYNC_GPU_COMMANDS_COMPLETE, /* flags= */ 0);
|
||||
checkGlError();
|
||||
// Due to specifics of OpenGL, it might happen that the fence creation command is not yet
|
||||
// sent into the GPU command queue, which can cause other threads to wait infinitely if
|
||||
// the glSyncWait/glClientSyncWait command went into the GPU earlier. Hence, we have to
|
||||
// call glFlush to ensure that glFenceSync is inside of the GPU command queue.
|
||||
GLES20.glFlush();
|
||||
checkGlError();
|
||||
return syncObject;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -384,17 +444,12 @@ public final class GlUtil {
|
||||
* <p>The {@code syncObject} must not be used after deletion.
|
||||
*/
|
||||
public static void deleteSyncObject(long syncObject) throws GlException {
|
||||
Api18.deleteSyncObject(syncObject);
|
||||
}
|
||||
deleteSyncObjectQuietly(syncObject);
|
||||
checkGlError(); }
|
||||
|
||||
/** Releases the GL sync object if set, suppressing any error. */
|
||||
public static void deleteSyncObjectQuietly(long syncObject) {
|
||||
try {
|
||||
// glDeleteSync ignores a 0-valued sync object.
|
||||
Api18.deleteSyncObject(syncObject);
|
||||
} catch (GlException unused) {
|
||||
// Suppress exceptions.
|
||||
}
|
||||
GLES30.glDeleteSync(syncObject);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -407,14 +462,14 @@ public final class GlUtil {
|
||||
// Fallback to using glFinish for synchronization when fence creation failed.
|
||||
GLES20.glFinish();
|
||||
} else {
|
||||
// If the sync object is set, we must be running API 18 or later.
|
||||
Api18.waitSync(syncObject);
|
||||
GLES30.glWaitSync(syncObject, /* flags= */ 0, GLES30.GL_TIMEOUT_IGNORED);
|
||||
checkGlError();
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the current {@link EGLContext context}. */
|
||||
public static EGLContext getCurrentContext() {
|
||||
return Api17.getCurrentContext();
|
||||
return EGL14.eglGetCurrentContext();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -491,7 +546,7 @@ public final class GlUtil {
|
||||
public static void focusEglSurface(
|
||||
EGLDisplay eglDisplay, EGLContext eglContext, EGLSurface eglSurface, int width, int height)
|
||||
throws GlException {
|
||||
Api17.focusRenderTarget(
|
||||
focusRenderTarget(
|
||||
eglDisplay, eglContext, eglSurface, /* framebuffer= */ 0, width, height);
|
||||
}
|
||||
|
||||
@ -507,7 +562,7 @@ public final class GlUtil {
|
||||
int width,
|
||||
int height)
|
||||
throws GlException {
|
||||
Api17.focusRenderTarget(eglDisplay, eglContext, eglSurface, framebuffer, width, height);
|
||||
focusRenderTarget(eglDisplay, eglContext, eglSurface, framebuffer, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -702,7 +757,20 @@ public final class GlUtil {
|
||||
*/
|
||||
public static void destroyEglContext(
|
||||
@Nullable EGLDisplay eglDisplay, @Nullable EGLContext eglContext) throws GlException {
|
||||
Api17.destroyEglContext(eglDisplay, eglContext);
|
||||
if (eglDisplay == null) {
|
||||
return;
|
||||
}
|
||||
EGL14.eglMakeCurrent(
|
||||
eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
|
||||
checkEglException("Error releasing context");
|
||||
if (eglContext != null) {
|
||||
EGL14.eglDestroyContext(eglDisplay, eglContext);
|
||||
checkEglException("Error destroying context");
|
||||
}
|
||||
EGL14.eglReleaseThread();
|
||||
checkEglException("Error releasing thread");
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
checkEglException("Error terminating display");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -711,7 +779,15 @@ public final class GlUtil {
|
||||
*/
|
||||
public static void destroyEglSurface(
|
||||
@Nullable EGLDisplay eglDisplay, @Nullable EGLSurface eglSurface) throws GlException {
|
||||
Api17.destroyEglSurface(eglDisplay, eglSurface);
|
||||
if (eglDisplay == null || eglSurface == null) {
|
||||
return;
|
||||
}
|
||||
if (EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW) == EGL_NO_SURFACE) {
|
||||
return;
|
||||
}
|
||||
|
||||
EGL14.eglDestroySurface(eglDisplay, eglSurface);
|
||||
checkEglException("Error destroying surface");
|
||||
}
|
||||
|
||||
/** Deletes a framebuffer, or silently ignores the method call if {@code fboId} is unused. */
|
||||
@ -737,201 +813,46 @@ public final class GlUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Api17 {
|
||||
private Api17() {}
|
||||
|
||||
@DoNotInline
|
||||
public static EGLDisplay getDefaultEglDisplay() throws GlException {
|
||||
EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
|
||||
checkGlException(!eglDisplay.equals(EGL14.EGL_NO_DISPLAY), "No EGL display.");
|
||||
checkGlException(
|
||||
EGL14.eglInitialize(
|
||||
eglDisplay,
|
||||
/* unusedMajor */ new int[1],
|
||||
/* majorOffset= */ 0,
|
||||
/* unusedMinor */ new int[1],
|
||||
/* minorOffset= */ 0),
|
||||
"Error in eglInitialize.");
|
||||
checkGlError();
|
||||
return eglDisplay;
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static EGLContext createEglContext(
|
||||
EGLContext sharedContext, EGLDisplay eglDisplay, int version, int[] configAttributes)
|
||||
throws GlException {
|
||||
int[] contextAttributes = {EGL_CONTEXT_CLIENT_VERSION, version, EGL14.EGL_NONE};
|
||||
EGLContext eglContext =
|
||||
EGL14.eglCreateContext(
|
||||
eglDisplay,
|
||||
getEglConfig(eglDisplay, configAttributes),
|
||||
sharedContext,
|
||||
contextAttributes,
|
||||
/* offset= */ 0);
|
||||
if (eglContext == null) {
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
throw new GlException(
|
||||
"eglCreateContext() failed to create a valid context. The device may not support EGL"
|
||||
+ " version "
|
||||
+ version);
|
||||
}
|
||||
checkGlError();
|
||||
return eglContext;
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static EGLContext getCurrentContext() {
|
||||
return EGL14.eglGetCurrentContext();
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
private static EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] attributes)
|
||||
throws GlException {
|
||||
EGLConfig[] eglConfigs = new EGLConfig[1];
|
||||
if (!EGL14.eglChooseConfig(
|
||||
eglDisplay,
|
||||
attributes,
|
||||
/* attrib_listOffset= */ 0,
|
||||
eglConfigs,
|
||||
/* configsOffset= */ 0,
|
||||
/* config_size= */ 1,
|
||||
/* unusedNumConfig */ new int[1],
|
||||
/* num_configOffset= */ 0)) {
|
||||
throw new GlException("eglChooseConfig failed.");
|
||||
}
|
||||
return eglConfigs[0];
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static boolean isExtensionSupported(String extensionName) {
|
||||
EGLDisplay display = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
|
||||
@Nullable String eglExtensions = EGL14.eglQueryString(display, EGL10.EGL_EXTENSIONS);
|
||||
return eglExtensions != null && eglExtensions.contains(extensionName);
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static int getContextMajorVersion() throws GlException {
|
||||
int[] currentEglContextVersion = new int[1];
|
||||
EGL14.eglQueryContext(
|
||||
EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY),
|
||||
EGL14.eglGetCurrentContext(),
|
||||
EGL_CONTEXT_CLIENT_VERSION,
|
||||
currentEglContextVersion,
|
||||
/* offset= */ 0);
|
||||
checkGlError();
|
||||
return currentEglContextVersion[0];
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static EGLSurface createEglSurface(
|
||||
EGLDisplay eglDisplay, Object surface, int[] configAttributes, int[] windowAttributes)
|
||||
throws GlException {
|
||||
EGLSurface eglSurface =
|
||||
EGL14.eglCreateWindowSurface(
|
||||
eglDisplay,
|
||||
getEglConfig(eglDisplay, configAttributes),
|
||||
surface,
|
||||
windowAttributes,
|
||||
/* offset= */ 0);
|
||||
checkEglException("Error creating a new EGL surface");
|
||||
return eglSurface;
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static EGLSurface createEglPbufferSurface(
|
||||
EGLDisplay eglDisplay, int[] configAttributes, int[] pbufferAttributes) throws GlException {
|
||||
EGLSurface eglSurface =
|
||||
EGL14.eglCreatePbufferSurface(
|
||||
eglDisplay,
|
||||
getEglConfig(eglDisplay, configAttributes),
|
||||
pbufferAttributes,
|
||||
/* offset= */ 0);
|
||||
checkEglException("Error creating a new EGL Pbuffer surface");
|
||||
return eglSurface;
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static void focusRenderTarget(
|
||||
EGLDisplay eglDisplay,
|
||||
EGLContext eglContext,
|
||||
EGLSurface eglSurface,
|
||||
int framebuffer,
|
||||
int width,
|
||||
int height)
|
||||
throws GlException {
|
||||
EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
|
||||
checkEglException("Error making context current");
|
||||
focusFramebufferUsingCurrentContext(framebuffer, width, height);
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static void destroyEglContext(
|
||||
@Nullable EGLDisplay eglDisplay, @Nullable EGLContext eglContext) throws GlException {
|
||||
if (eglDisplay == null) {
|
||||
return;
|
||||
}
|
||||
EGL14.eglMakeCurrent(
|
||||
eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
|
||||
checkEglException("Error releasing context");
|
||||
if (eglContext != null) {
|
||||
EGL14.eglDestroyContext(eglDisplay, eglContext);
|
||||
checkEglException("Error destroying context");
|
||||
}
|
||||
EGL14.eglReleaseThread();
|
||||
checkEglException("Error releasing thread");
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
checkEglException("Error terminating display");
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static void destroyEglSurface(
|
||||
@Nullable EGLDisplay eglDisplay, @Nullable EGLSurface eglSurface) throws GlException {
|
||||
if (eglDisplay == null || eglSurface == null) {
|
||||
return;
|
||||
}
|
||||
if (EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW) == EGL_NO_SURFACE) {
|
||||
return;
|
||||
}
|
||||
|
||||
EGL14.eglDestroySurface(eglDisplay, eglSurface);
|
||||
checkEglException("Error destroying surface");
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static void checkEglException(String errorMessage) throws GlException {
|
||||
int error = EGL14.eglGetError();
|
||||
if (error != EGL14.EGL_SUCCESS) {
|
||||
throw new GlException(errorMessage + ", error code: 0x" + Integer.toHexString(error));
|
||||
}
|
||||
private static EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] attributes)
|
||||
throws GlException {
|
||||
EGLConfig[] eglConfigs = new EGLConfig[1];
|
||||
if (!EGL14.eglChooseConfig(
|
||||
eglDisplay,
|
||||
attributes,
|
||||
/* attrib_listOffset= */ 0,
|
||||
eglConfigs,
|
||||
/* configsOffset= */ 0,
|
||||
/* config_size= */ 1,
|
||||
/* unusedNumConfig */ new int[1],
|
||||
/* num_configOffset= */ 0)) {
|
||||
throw new GlException("eglChooseConfig failed.");
|
||||
}
|
||||
return eglConfigs[0];
|
||||
}
|
||||
|
||||
private static final class Api18 {
|
||||
private Api18() {}
|
||||
private static boolean isExtensionSupported(String extensionName) {
|
||||
EGLDisplay display = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
|
||||
@Nullable String eglExtensions = EGL14.eglQueryString(display, EGL10.EGL_EXTENSIONS);
|
||||
return eglExtensions != null && eglExtensions.contains(extensionName);
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static long createSyncFence() throws GlException {
|
||||
long syncObject = GLES30.glFenceSync(GLES30.GL_SYNC_GPU_COMMANDS_COMPLETE, /* flags= */ 0);
|
||||
checkGlError();
|
||||
// Due to specifics of OpenGL, it might happen that the fence creation command is not yet
|
||||
// sent into the GPU command queue, which can cause other threads to wait infinitely if
|
||||
// the glSyncWait/glClientSyncWait command went into the GPU earlier. Hence, we have to
|
||||
// call glFlush to ensure that glFenceSync is inside of the GPU command queue.
|
||||
GLES20.glFlush();
|
||||
checkGlError();
|
||||
return syncObject;
|
||||
}
|
||||
private static void focusRenderTarget(
|
||||
EGLDisplay eglDisplay,
|
||||
EGLContext eglContext,
|
||||
EGLSurface eglSurface,
|
||||
int framebuffer,
|
||||
int width,
|
||||
int height)
|
||||
throws GlException {
|
||||
EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
|
||||
checkEglException("Error making context current");
|
||||
focusFramebufferUsingCurrentContext(framebuffer, width, height);
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static void deleteSyncObject(long syncObject) throws GlException {
|
||||
GLES30.glDeleteSync(syncObject);
|
||||
checkGlError();
|
||||
}
|
||||
|
||||
@DoNotInline
|
||||
public static void waitSync(long syncObject) throws GlException {
|
||||
GLES30.glWaitSync(syncObject, /* flags= */ 0, GLES30.GL_TIMEOUT_IGNORED);
|
||||
checkGlError();
|
||||
private static void checkEglException(String errorMessage) throws GlException {
|
||||
int error = EGL14.eglGetError();
|
||||
if (error != EGL14.EGL_SUCCESS) {
|
||||
throw new GlException(errorMessage + ", error code: 0x" + Integer.toHexString(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -803,7 +803,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
|
||||
} else {
|
||||
MediaCodecInfo codecInfo = getCodecInfo();
|
||||
if (codecInfo != null && shouldUsePlaceholderSurface(codecInfo)) {
|
||||
placeholderSurface = PlaceholderSurface.newInstanceV17(context, codecInfo.secure);
|
||||
placeholderSurface = PlaceholderSurface.newInstance(context, codecInfo.secure);
|
||||
displaySurface = placeholderSurface;
|
||||
}
|
||||
}
|
||||
@ -890,7 +890,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (placeholderSurface == null) {
|
||||
placeholderSurface = PlaceholderSurface.newInstanceV17(context, codecInfo.secure);
|
||||
placeholderSurface = PlaceholderSurface.newInstance(context, codecInfo.secure);
|
||||
}
|
||||
displaySurface = placeholderSurface;
|
||||
}
|
||||
|
@ -64,6 +64,14 @@ public final class PlaceholderSurface extends Surface {
|
||||
return secureMode != SECURE_MODE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #newInstance(Context, boolean)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static PlaceholderSurface newInstanceV17(Context context, boolean secure) {
|
||||
return newInstance(context, secure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a newly created placeholder surface. The surface must be released by calling {@link
|
||||
* #release} when it's no longer required.
|
||||
@ -76,12 +84,14 @@ public final class PlaceholderSurface extends Surface {
|
||||
* @throws IllegalStateException If a secure surface is requested on a device for which {@link
|
||||
* #isSecureSupported(Context)} returns {@code false}.
|
||||
*/
|
||||
public static PlaceholderSurface newInstanceV17(Context context, boolean secure) {
|
||||
public static PlaceholderSurface newInstance(Context context, boolean secure) {
|
||||
Assertions.checkState(!secure || isSecureSupported(context));
|
||||
PlaceholderSurfaceThread thread = new PlaceholderSurfaceThread();
|
||||
return thread.init(secure ? secureMode : SECURE_MODE_NONE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private PlaceholderSurface(
|
||||
PlaceholderSurfaceThread thread, SurfaceTexture surfaceTexture, boolean secure) {
|
||||
super(surfaceTexture);
|
||||
|
@ -161,7 +161,7 @@ public final class VideoFrameReleaseHelper {
|
||||
resetAdjustment();
|
||||
if (displayHelper != null) {
|
||||
checkNotNull(vsyncSampler).addObserver();
|
||||
displayHelper.register(this::updateDefaultDisplayRefreshRateParams);
|
||||
displayHelper.register();
|
||||
}
|
||||
updateSurfacePlaybackFrameRate(/* forceUpdate= */ false);
|
||||
}
|
||||
@ -418,16 +418,11 @@ public final class VideoFrameReleaseHelper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static DisplayHelper maybeBuildDisplayHelper(@Nullable Context context) {
|
||||
@Nullable DisplayHelper displayHelper = null;
|
||||
if (context != null) {
|
||||
context = context.getApplicationContext();
|
||||
displayHelper = DisplayHelperV17.maybeBuildNewInstance(context);
|
||||
if (displayHelper == null) {
|
||||
displayHelper = DisplayHelperV16.maybeBuildNewInstance(context);
|
||||
}
|
||||
}
|
||||
return displayHelper;
|
||||
private DisplayHelper maybeBuildDisplayHelper(@Nullable Context context) {
|
||||
if (context == null) { return null;}
|
||||
DisplayManager displayManager =
|
||||
(DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
|
||||
return displayManager != null ? new DisplayHelper(displayManager) : null;
|
||||
}
|
||||
|
||||
// Nested classes.
|
||||
@ -448,91 +443,28 @@ public final class VideoFrameReleaseHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper for listening to changes to the default display. */
|
||||
private interface DisplayHelper {
|
||||
|
||||
/** Listener for changes to the default display. */
|
||||
interface Listener {
|
||||
|
||||
/**
|
||||
* Called when the default display changes.
|
||||
*
|
||||
* @param defaultDisplay The default display, or {@code null} if a corresponding {@link
|
||||
* Display} object could not be obtained.
|
||||
*/
|
||||
void onDefaultDisplayChanged(@Nullable Display defaultDisplay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the helper, invoking {@link Listener#onDefaultDisplayChanged(Display)} to pass the
|
||||
* initial default display.
|
||||
*/
|
||||
void register(Listener listener);
|
||||
|
||||
/** Disables the helper. */
|
||||
void unregister();
|
||||
}
|
||||
|
||||
private static final class DisplayHelperV16 implements DisplayHelper {
|
||||
|
||||
@Nullable
|
||||
public static DisplayHelper maybeBuildNewInstance(Context context) {
|
||||
WindowManager windowManager =
|
||||
(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
return windowManager != null ? new DisplayHelperV16(windowManager) : null;
|
||||
}
|
||||
|
||||
private final WindowManager windowManager;
|
||||
|
||||
private DisplayHelperV16(WindowManager windowManager) {
|
||||
this.windowManager = windowManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Listener listener) {
|
||||
listener.onDefaultDisplayChanged(windowManager.getDefaultDisplay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DisplayHelperV17
|
||||
implements DisplayHelper, DisplayManager.DisplayListener {
|
||||
|
||||
@Nullable
|
||||
public static DisplayHelper maybeBuildNewInstance(Context context) {
|
||||
DisplayManager displayManager =
|
||||
(DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
|
||||
return displayManager != null ? new DisplayHelperV17(displayManager) : null;
|
||||
}
|
||||
private final class DisplayHelper
|
||||
implements DisplayManager.DisplayListener {
|
||||
|
||||
private final DisplayManager displayManager;
|
||||
@Nullable private Listener listener;
|
||||
|
||||
private DisplayHelperV17(DisplayManager displayManager) {
|
||||
public DisplayHelper(DisplayManager displayManager) {
|
||||
this.displayManager = displayManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Listener listener) {
|
||||
this.listener = listener;
|
||||
public void register() {
|
||||
displayManager.registerDisplayListener(this, Util.createHandlerForCurrentLooper());
|
||||
listener.onDefaultDisplayChanged(getDefaultDisplay());
|
||||
updateDefaultDisplayRefreshRateParams(getDefaultDisplay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
displayManager.unregisterDisplayListener(this);
|
||||
listener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayChanged(int displayId) {
|
||||
if (listener != null && displayId == Display.DEFAULT_DISPLAY) {
|
||||
listener.onDefaultDisplayChanged(getDefaultDisplay());
|
||||
if (displayId == Display.DEFAULT_DISPLAY) {
|
||||
updateDefaultDisplayRefreshRateParams(getDefaultDisplay());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user