279 lines
10 KiB
Java
279 lines
10 KiB
Java
package org.webrtc;
|
|
|
|
import android.annotation.TargetApi;
|
|
import android.graphics.SurfaceTexture;
|
|
import android.opengl.EGL14;
|
|
import android.opengl.EGLConfig;
|
|
import android.opengl.EGLContext;
|
|
import android.opengl.EGLDisplay;
|
|
import android.opengl.EGLExt;
|
|
import android.opengl.EGLSurface;
|
|
import android.os.Build;
|
|
import android.view.Surface;
|
|
import androidx.annotation.Nullable;
|
|
import c.d.b.a.a;
|
|
import h0.c.n0;
|
|
import org.webrtc.EglBase14;
|
|
@TargetApi(18)
|
|
public class EglBase14Impl implements EglBase14 {
|
|
private static final int CURRENT_SDK_VERSION = Build.VERSION.SDK_INT;
|
|
private static final int EGLExt_SDK_VERSION = 18;
|
|
private static final String TAG = "EglBase14Impl";
|
|
@Nullable
|
|
private EGLConfig eglConfig;
|
|
private EGLContext eglContext;
|
|
private EGLDisplay eglDisplay;
|
|
private EGLSurface eglSurface = EGL14.EGL_NO_SURFACE;
|
|
|
|
public static class Context implements EglBase14.Context {
|
|
private final EGLContext egl14Context;
|
|
|
|
public Context(EGLContext eGLContext) {
|
|
this.egl14Context = eGLContext;
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase.Context
|
|
@TargetApi(21)
|
|
public long getNativeEglContext() {
|
|
return EglBase14Impl.access$000() >= 21 ? this.egl14Context.getNativeHandle() : (long) this.egl14Context.getHandle();
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase14.Context
|
|
public EGLContext getRawContext() {
|
|
return this.egl14Context;
|
|
}
|
|
}
|
|
|
|
public EglBase14Impl(EGLContext eGLContext, int[] iArr) {
|
|
EGLDisplay eglDisplay = getEglDisplay();
|
|
this.eglDisplay = eglDisplay;
|
|
this.eglConfig = getEglConfig(eglDisplay, iArr);
|
|
int c2 = n0.c(iArr);
|
|
Logging.d("EglBase14Impl", "Using OpenGL ES version " + c2);
|
|
this.eglContext = createEglContext(eGLContext, this.eglDisplay, this.eglConfig, c2);
|
|
}
|
|
|
|
public static /* synthetic */ int access$000() {
|
|
return CURRENT_SDK_VERSION;
|
|
}
|
|
|
|
private void checkIsNotReleased() {
|
|
if (this.eglDisplay == EGL14.EGL_NO_DISPLAY || this.eglContext == EGL14.EGL_NO_CONTEXT || this.eglConfig == null) {
|
|
throw new RuntimeException("This object has been released");
|
|
}
|
|
}
|
|
|
|
private static EGLContext createEglContext(@Nullable EGLContext eGLContext, EGLDisplay eGLDisplay, EGLConfig eGLConfig, int i) {
|
|
EGLContext eglCreateContext;
|
|
if (eGLContext == null || eGLContext != EGL14.EGL_NO_CONTEXT) {
|
|
int[] iArr = {12440, i, 12344};
|
|
if (eGLContext == null) {
|
|
eGLContext = EGL14.EGL_NO_CONTEXT;
|
|
}
|
|
synchronized (EglBase.lock) {
|
|
eglCreateContext = EGL14.eglCreateContext(eGLDisplay, eGLConfig, eGLContext, iArr, 0);
|
|
}
|
|
if (eglCreateContext != EGL14.EGL_NO_CONTEXT) {
|
|
return eglCreateContext;
|
|
}
|
|
StringBuilder K = a.K("Failed to create EGL context: 0x");
|
|
K.append(Integer.toHexString(EGL14.eglGetError()));
|
|
throw new RuntimeException(K.toString());
|
|
}
|
|
throw new RuntimeException("Invalid sharedContext");
|
|
}
|
|
|
|
private void createSurfaceInternal(Object obj) {
|
|
if ((obj instanceof Surface) || (obj instanceof SurfaceTexture)) {
|
|
checkIsNotReleased();
|
|
if (this.eglSurface == EGL14.EGL_NO_SURFACE) {
|
|
EGLSurface eglCreateWindowSurface = EGL14.eglCreateWindowSurface(this.eglDisplay, this.eglConfig, obj, new int[]{12344}, 0);
|
|
this.eglSurface = eglCreateWindowSurface;
|
|
if (eglCreateWindowSurface == EGL14.EGL_NO_SURFACE) {
|
|
StringBuilder K = a.K("Failed to create window surface: 0x");
|
|
K.append(Integer.toHexString(EGL14.eglGetError()));
|
|
throw new RuntimeException(K.toString());
|
|
}
|
|
return;
|
|
}
|
|
throw new RuntimeException("Already has an EGLSurface");
|
|
}
|
|
throw new IllegalStateException("Input must be either a Surface or SurfaceTexture");
|
|
}
|
|
|
|
private static EGLConfig getEglConfig(EGLDisplay eGLDisplay, int[] iArr) {
|
|
EGLConfig[] eGLConfigArr = new EGLConfig[1];
|
|
int[] iArr2 = new int[1];
|
|
if (!EGL14.eglChooseConfig(eGLDisplay, iArr, 0, eGLConfigArr, 0, 1, iArr2, 0)) {
|
|
StringBuilder K = a.K("eglChooseConfig failed: 0x");
|
|
K.append(Integer.toHexString(EGL14.eglGetError()));
|
|
throw new RuntimeException(K.toString());
|
|
} else if (iArr2[0] > 0) {
|
|
EGLConfig eGLConfig = eGLConfigArr[0];
|
|
if (eGLConfig != null) {
|
|
return eGLConfig;
|
|
}
|
|
throw new RuntimeException("eglChooseConfig returned null");
|
|
} else {
|
|
throw new RuntimeException("Unable to find any matching EGL config");
|
|
}
|
|
}
|
|
|
|
private static EGLDisplay getEglDisplay() {
|
|
EGLDisplay eglGetDisplay = EGL14.eglGetDisplay(0);
|
|
if (eglGetDisplay != EGL14.EGL_NO_DISPLAY) {
|
|
int[] iArr = new int[2];
|
|
if (EGL14.eglInitialize(eglGetDisplay, iArr, 0, iArr, 1)) {
|
|
return eglGetDisplay;
|
|
}
|
|
StringBuilder K = a.K("Unable to initialize EGL14: 0x");
|
|
K.append(Integer.toHexString(EGL14.eglGetError()));
|
|
throw new RuntimeException(K.toString());
|
|
}
|
|
StringBuilder K2 = a.K("Unable to get EGL14 display: 0x");
|
|
K2.append(Integer.toHexString(EGL14.eglGetError()));
|
|
throw new RuntimeException(K2.toString());
|
|
}
|
|
|
|
public static boolean isEGL14Supported() {
|
|
StringBuilder K = a.K("SDK version: ");
|
|
int i = CURRENT_SDK_VERSION;
|
|
K.append(i);
|
|
K.append(". isEGL14Supported: ");
|
|
K.append(i >= 18);
|
|
Logging.d("EglBase14Impl", K.toString());
|
|
return i >= 18;
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public void createDummyPbufferSurface() {
|
|
createPbufferSurface(1, 1);
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public void createPbufferSurface(int i, int i2) {
|
|
checkIsNotReleased();
|
|
if (this.eglSurface == EGL14.EGL_NO_SURFACE) {
|
|
EGLSurface eglCreatePbufferSurface = EGL14.eglCreatePbufferSurface(this.eglDisplay, this.eglConfig, new int[]{12375, i, 12374, i2, 12344}, 0);
|
|
this.eglSurface = eglCreatePbufferSurface;
|
|
if (eglCreatePbufferSurface == EGL14.EGL_NO_SURFACE) {
|
|
StringBuilder M = a.M("Failed to create pixel buffer surface with size ", i, "x", i2, ": 0x");
|
|
M.append(Integer.toHexString(EGL14.eglGetError()));
|
|
throw new RuntimeException(M.toString());
|
|
}
|
|
return;
|
|
}
|
|
throw new RuntimeException("Already has an EGLSurface");
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public void createSurface(SurfaceTexture surfaceTexture) {
|
|
createSurfaceInternal(surfaceTexture);
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public void createSurface(Surface surface) {
|
|
createSurfaceInternal(surface);
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public void detachCurrent() {
|
|
synchronized (EglBase.lock) {
|
|
EGLDisplay eGLDisplay = this.eglDisplay;
|
|
EGLSurface eGLSurface = EGL14.EGL_NO_SURFACE;
|
|
if (!EGL14.eglMakeCurrent(eGLDisplay, eGLSurface, eGLSurface, EGL14.EGL_NO_CONTEXT)) {
|
|
throw new RuntimeException("eglDetachCurrent failed: 0x" + Integer.toHexString(EGL14.eglGetError()));
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public Context getEglBaseContext() {
|
|
return new Context(this.eglContext);
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public boolean hasSurface() {
|
|
return this.eglSurface != EGL14.EGL_NO_SURFACE;
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public void makeCurrent() {
|
|
checkIsNotReleased();
|
|
if (this.eglSurface != EGL14.EGL_NO_SURFACE) {
|
|
synchronized (EglBase.lock) {
|
|
EGLDisplay eGLDisplay = this.eglDisplay;
|
|
EGLSurface eGLSurface = this.eglSurface;
|
|
if (!EGL14.eglMakeCurrent(eGLDisplay, eGLSurface, eGLSurface, this.eglContext)) {
|
|
throw new RuntimeException("eglMakeCurrent failed: 0x" + Integer.toHexString(EGL14.eglGetError()));
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
throw new RuntimeException("No EGLSurface - can't make current");
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public void release() {
|
|
checkIsNotReleased();
|
|
releaseSurface();
|
|
detachCurrent();
|
|
synchronized (EglBase.lock) {
|
|
EGL14.eglDestroyContext(this.eglDisplay, this.eglContext);
|
|
}
|
|
EGL14.eglReleaseThread();
|
|
EGL14.eglTerminate(this.eglDisplay);
|
|
this.eglContext = EGL14.EGL_NO_CONTEXT;
|
|
this.eglDisplay = EGL14.EGL_NO_DISPLAY;
|
|
this.eglConfig = null;
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public void releaseSurface() {
|
|
EGLSurface eGLSurface = this.eglSurface;
|
|
if (eGLSurface != EGL14.EGL_NO_SURFACE) {
|
|
EGL14.eglDestroySurface(this.eglDisplay, eGLSurface);
|
|
this.eglSurface = EGL14.EGL_NO_SURFACE;
|
|
}
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public int surfaceHeight() {
|
|
int[] iArr = new int[1];
|
|
EGL14.eglQuerySurface(this.eglDisplay, this.eglSurface, 12374, iArr, 0);
|
|
return iArr[0];
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public int surfaceWidth() {
|
|
int[] iArr = new int[1];
|
|
EGL14.eglQuerySurface(this.eglDisplay, this.eglSurface, 12375, iArr, 0);
|
|
return iArr[0];
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public void swapBuffers() {
|
|
checkIsNotReleased();
|
|
if (this.eglSurface != EGL14.EGL_NO_SURFACE) {
|
|
synchronized (EglBase.lock) {
|
|
EGL14.eglSwapBuffers(this.eglDisplay, this.eglSurface);
|
|
}
|
|
return;
|
|
}
|
|
throw new RuntimeException("No EGLSurface - can't swap buffers");
|
|
}
|
|
|
|
@Override // org.webrtc.EglBase
|
|
public void swapBuffers(long j) {
|
|
checkIsNotReleased();
|
|
if (this.eglSurface != EGL14.EGL_NO_SURFACE) {
|
|
synchronized (EglBase.lock) {
|
|
EGLExt.eglPresentationTimeANDROID(this.eglDisplay, this.eglSurface, j);
|
|
EGL14.eglSwapBuffers(this.eglDisplay, this.eglSurface);
|
|
}
|
|
return;
|
|
}
|
|
throw new RuntimeException("No EGLSurface - can't swap buffers");
|
|
}
|
|
}
|