mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
Allow EglBase instances to share EGLConnection.
This enables clients of EglBase to keep using it but share underlying EGLContext with other clients. go/meet-android-eglcontext-reduction Bug: b/225229697 Change-Id: I42719f25be7db169c39878b57a5f1487e3c1894e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/301941 Reviewed-by: Magnus Jedvert <magjed@webrtc.org> Commit-Queue: Linus Nilsson <lnilsson@webrtc.org> Reviewed-by: Xavier Lepaul <xalep@webrtc.org> Cr-Commit-Position: refs/heads/main@{#39961}
This commit is contained in:
parent
9ecc76e15b
commit
df4bc33e11
5 changed files with 263 additions and 67 deletions
|
@ -34,6 +34,38 @@ public interface EglBase {
|
|||
long getNativeEglContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the objects needed to interact with EGL that are independent of a particular EGLSurface.
|
||||
* In practice this means EGLContext, EGLDisplay and EGLConfig objects. Separating them out in a
|
||||
* standalone object allows for multiple EglBase instances to use the same underlying EGLContext,
|
||||
* while still operating on their own EGLSurface.
|
||||
*/
|
||||
public interface EglConnection extends RefCounted {
|
||||
/** Analogous to corresponding EglBase#create below. */
|
||||
public static EglConnection create(@Nullable Context sharedContext, int[] configAttributes) {
|
||||
if (sharedContext == null) {
|
||||
return EglConnection.createEgl14(configAttributes);
|
||||
} else if (sharedContext instanceof EglBase14.Context) {
|
||||
return new EglBase14Impl.EglConnection(
|
||||
((EglBase14.Context) sharedContext).getRawContext(), configAttributes);
|
||||
} else if (sharedContext instanceof EglBase10.Context) {
|
||||
return new EglBase10Impl.EglConnection(
|
||||
((EglBase10.Context) sharedContext).getRawContext(), configAttributes);
|
||||
}
|
||||
throw new IllegalArgumentException("Unrecognized Context");
|
||||
}
|
||||
|
||||
/** Analogous to corresponding EglBase#createEgl10 below. */
|
||||
public static EglConnection createEgl10(int[] configAttributes) {
|
||||
return new EglBase10Impl.EglConnection(/* sharedContext= */ null, configAttributes);
|
||||
}
|
||||
|
||||
/** Analogous to corresponding EglBase#createEgl14 below. */
|
||||
public static EglConnection createEgl14(int[] configAttributes) {
|
||||
return new EglBase14Impl.EglConnection(/* sharedContext= */ null, configAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
// According to the documentation, EGL can be used from multiple threads at the same time if each
|
||||
// thread has its own EGLContext, but in practice it deadlocks on some devices when doing this.
|
||||
// Therefore, synchronize on this global lock before calling dangerous EGL functions that might
|
||||
|
@ -145,6 +177,24 @@ public interface EglBase {
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new EglBase with a shared EglConnection. EglBase instances sharing the same
|
||||
* EglConnection should be used on the same thread to avoid the underlying EGLContext being made
|
||||
* current on multiple threads. It is up to the client of EglBase to ensure that instances with a
|
||||
* shared EglConnection are current on that thread before each use since other EglBase instances
|
||||
* may have used the same EGLContext since the last interaction.
|
||||
*/
|
||||
public static EglBase create(EglConnection eglConnection) {
|
||||
if (eglConnection == null) {
|
||||
return create();
|
||||
} else if (eglConnection instanceof EglBase14Impl.EglConnection) {
|
||||
return new EglBase14Impl((EglBase14Impl.EglConnection) eglConnection);
|
||||
} else if (eglConnection instanceof EglBase10Impl.EglConnection) {
|
||||
return new EglBase10Impl((EglBase10Impl.EglConnection) eglConnection);
|
||||
}
|
||||
throw new IllegalArgumentException("Unrecognized EglConnection");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new context with the specified config attributes, sharing data with `sharedContext`.
|
||||
* If `sharedContext` is null, a root EGL 1.4 context is created.
|
||||
|
|
|
@ -10,11 +10,24 @@
|
|||
|
||||
package org.webrtc;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.egl.EGLContext;
|
||||
import javax.microedition.khronos.egl.EGLDisplay;
|
||||
|
||||
/** EGL 1.0 implementation of EglBase. */
|
||||
public interface EglBase10 extends EglBase {
|
||||
interface Context extends EglBase.Context {
|
||||
EGLContext getRawContext();
|
||||
}
|
||||
|
||||
interface EglConnection extends EglBase.EglConnection {
|
||||
EGL10 getEgl();
|
||||
|
||||
EGLContext getContext();
|
||||
|
||||
EGLDisplay getDisplay();
|
||||
|
||||
EGLConfig getConfig();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,21 @@
|
|||
|
||||
package org.webrtc;
|
||||
|
||||
import android.opengl.EGLConfig;
|
||||
import android.opengl.EGLContext;
|
||||
import android.opengl.EGLDisplay;
|
||||
|
||||
/** EGL 1.4 implementation of EglBase. */
|
||||
public interface EglBase14 extends EglBase {
|
||||
interface Context extends EglBase.Context {
|
||||
EGLContext getRawContext();
|
||||
}
|
||||
|
||||
interface EglConnection extends EglBase.EglConnection {
|
||||
EGLContext getContext();
|
||||
|
||||
EGLDisplay getDisplay();
|
||||
|
||||
EGLConfig getConfig();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ package org.webrtc;
|
|||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.opengl.EGL14;
|
||||
import android.opengl.GLException;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
|
@ -33,11 +32,10 @@ class EglBase10Impl implements EglBase10 {
|
|||
// This constant is taken from EGL14.EGL_CONTEXT_CLIENT_VERSION.
|
||||
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
|
||||
|
||||
private final EGL10 egl;
|
||||
private EGLContext eglContext;
|
||||
@Nullable private EGLConfig eglConfig;
|
||||
private EGLDisplay eglDisplay;
|
||||
private static final EglConnection EGL_NO_CONNECTION = new EglConnection();
|
||||
|
||||
private EGLSurface eglSurface = EGL10.EGL_NO_SURFACE;
|
||||
private EglConnection eglConnection;
|
||||
|
||||
// EGL wrapper for an actual EGLContext.
|
||||
private static class Context implements EglBase10.Context {
|
||||
|
@ -90,14 +88,80 @@ class EglBase10Impl implements EglBase10 {
|
|||
}
|
||||
}
|
||||
|
||||
// Create a new context with the specified config type, sharing data with sharedContext.
|
||||
public EglBase10Impl(EGLContext sharedContext, int[] configAttributes) {
|
||||
this.egl = (EGL10) EGLContext.getEGL();
|
||||
eglDisplay = getEglDisplay();
|
||||
public static class EglConnection implements EglBase10.EglConnection {
|
||||
private final EGL10 egl;
|
||||
private final EGLContext eglContext;
|
||||
private final EGLDisplay eglDisplay;
|
||||
private final EGLConfig eglConfig;
|
||||
private final RefCountDelegate refCountDelegate;
|
||||
|
||||
public EglConnection(EGLContext sharedContext, int[] configAttributes) {
|
||||
egl = (EGL10) EGLContext.getEGL();
|
||||
eglDisplay = getEglDisplay(egl);
|
||||
eglConfig = getEglConfig(egl, eglDisplay, configAttributes);
|
||||
final int openGlesVersion = EglBase.getOpenGlesVersionFromConfig(configAttributes);
|
||||
Logging.d(TAG, "Using OpenGL ES version " + openGlesVersion);
|
||||
eglContext = createEglContext(sharedContext, eglDisplay, eglConfig, openGlesVersion);
|
||||
eglContext = createEglContext(egl, sharedContext, eglDisplay, eglConfig, openGlesVersion);
|
||||
|
||||
// Ref count delegate with release callback.
|
||||
refCountDelegate = new RefCountDelegate(() -> {
|
||||
synchronized (EglBase.lock) {
|
||||
egl.eglMakeCurrent(
|
||||
eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
|
||||
}
|
||||
egl.eglDestroyContext(eglDisplay, eglContext);
|
||||
egl.eglTerminate(eglDisplay);
|
||||
});
|
||||
}
|
||||
|
||||
// Returns a "null" EglConnection. Useful to represent a released instance with default values.
|
||||
private EglConnection() {
|
||||
egl = (EGL10) EGLContext.getEGL();
|
||||
eglContext = EGL10.EGL_NO_CONTEXT;
|
||||
eglDisplay = EGL10.EGL_NO_DISPLAY;
|
||||
eglConfig = null;
|
||||
refCountDelegate = new RefCountDelegate(() -> {});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void retain() {
|
||||
refCountDelegate.retain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
refCountDelegate.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EGL10 getEgl() {
|
||||
return egl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EGLContext getContext() {
|
||||
return eglContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EGLDisplay getDisplay() {
|
||||
return eglDisplay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EGLConfig getConfig() {
|
||||
return eglConfig;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new context with the specified config type, sharing data with sharedContext.
|
||||
public EglBase10Impl(EGLContext sharedContext, int[] configAttributes) {
|
||||
this.eglConnection = new EglConnection(sharedContext, configAttributes);
|
||||
}
|
||||
|
||||
public EglBase10Impl(EglConnection eglConnection) {
|
||||
this.eglConnection = eglConnection;
|
||||
this.eglConnection.retain();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -186,8 +250,11 @@ class EglBase10Impl implements EglBase10 {
|
|||
if (eglSurface != EGL10.EGL_NO_SURFACE) {
|
||||
throw new RuntimeException("Already has an EGLSurface");
|
||||
}
|
||||
|
||||
EGL10 egl = eglConnection.getEgl();
|
||||
int[] surfaceAttribs = {EGL10.EGL_NONE};
|
||||
eglSurface = egl.eglCreateWindowSurface(eglDisplay, eglConfig, nativeWindow, surfaceAttribs);
|
||||
eglSurface = egl.eglCreateWindowSurface(
|
||||
eglConnection.getDisplay(), eglConnection.getConfig(), nativeWindow, surfaceAttribs);
|
||||
if (eglSurface == EGL10.EGL_NO_SURFACE) {
|
||||
throw new GLException(egl.eglGetError(),
|
||||
"Failed to create window surface: 0x" + Integer.toHexString(egl.eglGetError()));
|
||||
|
@ -206,8 +273,10 @@ class EglBase10Impl implements EglBase10 {
|
|||
if (eglSurface != EGL10.EGL_NO_SURFACE) {
|
||||
throw new RuntimeException("Already has an EGLSurface");
|
||||
}
|
||||
EGL10 egl = eglConnection.getEgl();
|
||||
int[] surfaceAttribs = {EGL10.EGL_WIDTH, width, EGL10.EGL_HEIGHT, height, EGL10.EGL_NONE};
|
||||
eglSurface = egl.eglCreatePbufferSurface(eglDisplay, eglConfig, surfaceAttribs);
|
||||
eglSurface = egl.eglCreatePbufferSurface(
|
||||
eglConnection.getDisplay(), eglConnection.getConfig(), surfaceAttribs);
|
||||
if (eglSurface == EGL10.EGL_NO_SURFACE) {
|
||||
throw new GLException(egl.eglGetError(),
|
||||
"Failed to create pixel buffer surface with size " + width + "x" + height + ": 0x"
|
||||
|
@ -217,7 +286,8 @@ class EglBase10Impl implements EglBase10 {
|
|||
|
||||
@Override
|
||||
public org.webrtc.EglBase.Context getEglBaseContext() {
|
||||
return new Context(egl, eglContext, eglConfig);
|
||||
return new Context(
|
||||
eglConnection.getEgl(), eglConnection.getContext(), eglConnection.getConfig());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -228,28 +298,29 @@ class EglBase10Impl implements EglBase10 {
|
|||
@Override
|
||||
public int surfaceWidth() {
|
||||
final int widthArray[] = new int[1];
|
||||
egl.eglQuerySurface(eglDisplay, eglSurface, EGL10.EGL_WIDTH, widthArray);
|
||||
eglConnection.getEgl().eglQuerySurface(
|
||||
eglConnection.getDisplay(), eglSurface, EGL10.EGL_WIDTH, widthArray);
|
||||
return widthArray[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int surfaceHeight() {
|
||||
final int heightArray[] = new int[1];
|
||||
egl.eglQuerySurface(eglDisplay, eglSurface, EGL10.EGL_HEIGHT, heightArray);
|
||||
eglConnection.getEgl().eglQuerySurface(
|
||||
eglConnection.getDisplay(), eglSurface, EGL10.EGL_HEIGHT, heightArray);
|
||||
return heightArray[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseSurface() {
|
||||
if (eglSurface != EGL10.EGL_NO_SURFACE) {
|
||||
egl.eglDestroySurface(eglDisplay, eglSurface);
|
||||
eglConnection.getEgl().eglDestroySurface(eglConnection.getDisplay(), eglSurface);
|
||||
eglSurface = EGL10.EGL_NO_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIsNotReleased() {
|
||||
if (eglDisplay == EGL10.EGL_NO_DISPLAY || eglContext == EGL10.EGL_NO_CONTEXT
|
||||
|| eglConfig == null) {
|
||||
if (eglConnection == EGL_NO_CONNECTION) {
|
||||
throw new RuntimeException("This object has been released");
|
||||
}
|
||||
}
|
||||
|
@ -258,12 +329,8 @@ class EglBase10Impl implements EglBase10 {
|
|||
public void release() {
|
||||
checkIsNotReleased();
|
||||
releaseSurface();
|
||||
detachCurrent();
|
||||
egl.eglDestroyContext(eglDisplay, eglContext);
|
||||
egl.eglTerminate(eglDisplay);
|
||||
eglContext = EGL10.EGL_NO_CONTEXT;
|
||||
eglDisplay = EGL10.EGL_NO_DISPLAY;
|
||||
eglConfig = null;
|
||||
eglConnection.release();
|
||||
eglConnection = EGL_NO_CONNECTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -273,7 +340,9 @@ class EglBase10Impl implements EglBase10 {
|
|||
throw new RuntimeException("No EGLSurface - can't make current");
|
||||
}
|
||||
synchronized (EglBase.lock) {
|
||||
if (!egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
|
||||
EGL10 egl = eglConnection.getEgl();
|
||||
if (!egl.eglMakeCurrent(
|
||||
eglConnection.getDisplay(), eglSurface, eglSurface, eglConnection.getContext())) {
|
||||
throw new GLException(egl.eglGetError(),
|
||||
"eglMakeCurrent failed: 0x" + Integer.toHexString(egl.eglGetError()));
|
||||
}
|
||||
|
@ -284,8 +353,9 @@ class EglBase10Impl implements EglBase10 {
|
|||
@Override
|
||||
public void detachCurrent() {
|
||||
synchronized (EglBase.lock) {
|
||||
if (!egl.eglMakeCurrent(
|
||||
eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT)) {
|
||||
EGL10 egl = eglConnection.getEgl();
|
||||
if (!egl.eglMakeCurrent(eglConnection.getDisplay(), EGL10.EGL_NO_SURFACE,
|
||||
EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT)) {
|
||||
throw new GLException(egl.eglGetError(),
|
||||
"eglDetachCurrent failed: 0x" + Integer.toHexString(egl.eglGetError()));
|
||||
}
|
||||
|
@ -299,7 +369,7 @@ class EglBase10Impl implements EglBase10 {
|
|||
throw new RuntimeException("No EGLSurface - can't swap buffers");
|
||||
}
|
||||
synchronized (EglBase.lock) {
|
||||
egl.eglSwapBuffers(eglDisplay, eglSurface);
|
||||
eglConnection.getEgl().eglSwapBuffers(eglConnection.getDisplay(), eglSurface);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +380,7 @@ class EglBase10Impl implements EglBase10 {
|
|||
}
|
||||
|
||||
// Return an EGLDisplay, or die trying.
|
||||
private EGLDisplay getEglDisplay() {
|
||||
private static EGLDisplay getEglDisplay(EGL10 egl) {
|
||||
EGLDisplay eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
||||
if (eglDisplay == EGL10.EGL_NO_DISPLAY) {
|
||||
throw new GLException(egl.eglGetError(),
|
||||
|
@ -343,8 +413,8 @@ class EglBase10Impl implements EglBase10 {
|
|||
}
|
||||
|
||||
// Return an EGLConfig, or die trying.
|
||||
private EGLContext createEglContext(@Nullable EGLContext sharedContext, EGLDisplay eglDisplay,
|
||||
EGLConfig eglConfig, int openGlesVersion) {
|
||||
private static EGLContext createEglContext(EGL10 egl, @Nullable EGLContext sharedContext,
|
||||
EGLDisplay eglDisplay, EGLConfig eglConfig, int openGlesVersion) {
|
||||
if (sharedContext != null && sharedContext == EGL10.EGL_NO_CONTEXT) {
|
||||
throw new RuntimeException("Invalid sharedContext");
|
||||
}
|
||||
|
|
|
@ -18,10 +18,8 @@ import android.opengl.EGLDisplay;
|
|||
import android.opengl.EGLExt;
|
||||
import android.opengl.EGLSurface;
|
||||
import android.opengl.GLException;
|
||||
import android.os.Build;
|
||||
import android.view.Surface;
|
||||
import androidx.annotation.Nullable;
|
||||
import org.webrtc.EglBase;
|
||||
|
||||
/**
|
||||
* Holds EGL state and utility methods for handling an EGL14 EGLContext, an EGLDisplay,
|
||||
|
@ -30,10 +28,10 @@ import org.webrtc.EglBase;
|
|||
@SuppressWarnings("ReferenceEquality") // We want to compare to EGL14 constants.
|
||||
class EglBase14Impl implements EglBase14 {
|
||||
private static final String TAG = "EglBase14Impl";
|
||||
private EGLContext eglContext;
|
||||
@Nullable private EGLConfig eglConfig;
|
||||
private EGLDisplay eglDisplay;
|
||||
private static final EglConnection EGL_NO_CONNECTION = new EglConnection();
|
||||
|
||||
private EGLSurface eglSurface = EGL14.EGL_NO_SURFACE;
|
||||
private EglConnection eglConnection;
|
||||
|
||||
public static class Context implements EglBase14.Context {
|
||||
private final EGLContext egl14Context;
|
||||
|
@ -53,14 +51,74 @@ class EglBase14Impl implements EglBase14 {
|
|||
}
|
||||
}
|
||||
|
||||
// Create a new context with the specified config type, sharing data with sharedContext.
|
||||
// `sharedContext` may be null.
|
||||
public EglBase14Impl(EGLContext sharedContext, int[] configAttributes) {
|
||||
public static class EglConnection implements EglBase14.EglConnection {
|
||||
private final EGLContext eglContext;
|
||||
private final EGLDisplay eglDisplay;
|
||||
private final EGLConfig eglConfig;
|
||||
private final RefCountDelegate refCountDelegate;
|
||||
|
||||
public EglConnection(EGLContext sharedContext, int[] configAttributes) {
|
||||
eglDisplay = getEglDisplay();
|
||||
eglConfig = getEglConfig(eglDisplay, configAttributes);
|
||||
final int openGlesVersion = EglBase.getOpenGlesVersionFromConfig(configAttributes);
|
||||
Logging.d(TAG, "Using OpenGL ES version " + openGlesVersion);
|
||||
eglContext = createEglContext(sharedContext, eglDisplay, eglConfig, openGlesVersion);
|
||||
|
||||
// Ref count delegate with release callback.
|
||||
refCountDelegate = new RefCountDelegate(() -> {
|
||||
synchronized (EglBase.lock) {
|
||||
EGL14.eglMakeCurrent(
|
||||
eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
|
||||
EGL14.eglDestroyContext(eglDisplay, eglContext);
|
||||
}
|
||||
EGL14.eglReleaseThread();
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
});
|
||||
}
|
||||
|
||||
// Returns a "null" EglConnection. Useful to represent a released instance with default values.
|
||||
private EglConnection() {
|
||||
eglContext = EGL14.EGL_NO_CONTEXT;
|
||||
eglDisplay = EGL14.EGL_NO_DISPLAY;
|
||||
eglConfig = null;
|
||||
refCountDelegate = new RefCountDelegate(() -> {});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void retain() {
|
||||
refCountDelegate.retain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
refCountDelegate.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EGLContext getContext() {
|
||||
return eglContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EGLDisplay getDisplay() {
|
||||
return eglDisplay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EGLConfig getConfig() {
|
||||
return eglConfig;
|
||||
}
|
||||
}
|
||||
// Create a new context with the specified config type, sharing data with sharedContext.
|
||||
// `sharedContext` may be null.
|
||||
public EglBase14Impl(EGLContext sharedContext, int[] configAttributes) {
|
||||
this.eglConnection = new EglConnection(sharedContext, configAttributes);
|
||||
}
|
||||
|
||||
// Create a new EglBase using an existing, possibly externally managed, EglConnection.
|
||||
public EglBase14Impl(EglConnection eglConnection) {
|
||||
this.eglConnection = eglConnection;
|
||||
this.eglConnection.retain();
|
||||
}
|
||||
|
||||
// Create EGLSurface from the Android Surface.
|
||||
|
@ -85,7 +143,8 @@ class EglBase14Impl implements EglBase14 {
|
|||
throw new RuntimeException("Already has an EGLSurface");
|
||||
}
|
||||
int[] surfaceAttribs = {EGL14.EGL_NONE};
|
||||
eglSurface = EGL14.eglCreateWindowSurface(eglDisplay, eglConfig, surface, surfaceAttribs, 0);
|
||||
eglSurface = EGL14.eglCreateWindowSurface(
|
||||
eglConnection.getDisplay(), eglConnection.getConfig(), surface, surfaceAttribs, 0);
|
||||
if (eglSurface == EGL14.EGL_NO_SURFACE) {
|
||||
throw new GLException(EGL14.eglGetError(),
|
||||
"Failed to create window surface: 0x" + Integer.toHexString(EGL14.eglGetError()));
|
||||
|
@ -104,7 +163,8 @@ class EglBase14Impl implements EglBase14 {
|
|||
throw new RuntimeException("Already has an EGLSurface");
|
||||
}
|
||||
int[] surfaceAttribs = {EGL14.EGL_WIDTH, width, EGL14.EGL_HEIGHT, height, EGL14.EGL_NONE};
|
||||
eglSurface = EGL14.eglCreatePbufferSurface(eglDisplay, eglConfig, surfaceAttribs, 0);
|
||||
eglSurface = EGL14.eglCreatePbufferSurface(
|
||||
eglConnection.getDisplay(), eglConnection.getConfig(), surfaceAttribs, 0);
|
||||
if (eglSurface == EGL14.EGL_NO_SURFACE) {
|
||||
throw new GLException(EGL14.eglGetError(),
|
||||
"Failed to create pixel buffer surface with size " + width + "x" + height + ": 0x"
|
||||
|
@ -114,7 +174,7 @@ class EglBase14Impl implements EglBase14 {
|
|||
|
||||
@Override
|
||||
public Context getEglBaseContext() {
|
||||
return new Context(eglContext);
|
||||
return new Context(eglConnection.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -124,29 +184,28 @@ class EglBase14Impl implements EglBase14 {
|
|||
|
||||
@Override
|
||||
public int surfaceWidth() {
|
||||
final int widthArray[] = new int[1];
|
||||
EGL14.eglQuerySurface(eglDisplay, eglSurface, EGL14.EGL_WIDTH, widthArray, 0);
|
||||
final int[] widthArray = new int[1];
|
||||
EGL14.eglQuerySurface(eglConnection.getDisplay(), eglSurface, EGL14.EGL_WIDTH, widthArray, 0);
|
||||
return widthArray[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int surfaceHeight() {
|
||||
final int heightArray[] = new int[1];
|
||||
EGL14.eglQuerySurface(eglDisplay, eglSurface, EGL14.EGL_HEIGHT, heightArray, 0);
|
||||
final int[] heightArray = new int[1];
|
||||
EGL14.eglQuerySurface(eglConnection.getDisplay(), eglSurface, EGL14.EGL_HEIGHT, heightArray, 0);
|
||||
return heightArray[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseSurface() {
|
||||
if (eglSurface != EGL14.EGL_NO_SURFACE) {
|
||||
EGL14.eglDestroySurface(eglDisplay, eglSurface);
|
||||
EGL14.eglDestroySurface(eglConnection.getDisplay(), eglSurface);
|
||||
eglSurface = EGL14.EGL_NO_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIsNotReleased() {
|
||||
if (eglDisplay == EGL14.EGL_NO_DISPLAY || eglContext == EGL14.EGL_NO_CONTEXT
|
||||
|| eglConfig == null) {
|
||||
if (eglConnection == EGL_NO_CONNECTION) {
|
||||
throw new RuntimeException("This object has been released");
|
||||
}
|
||||
}
|
||||
|
@ -155,15 +214,8 @@ class EglBase14Impl implements EglBase14 {
|
|||
public void release() {
|
||||
checkIsNotReleased();
|
||||
releaseSurface();
|
||||
detachCurrent();
|
||||
synchronized (EglBase.lock) {
|
||||
EGL14.eglDestroyContext(eglDisplay, eglContext);
|
||||
}
|
||||
EGL14.eglReleaseThread();
|
||||
EGL14.eglTerminate(eglDisplay);
|
||||
eglContext = EGL14.EGL_NO_CONTEXT;
|
||||
eglDisplay = EGL14.EGL_NO_DISPLAY;
|
||||
eglConfig = null;
|
||||
eglConnection.release();
|
||||
eglConnection = EGL_NO_CONNECTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -173,7 +225,8 @@ class EglBase14Impl implements EglBase14 {
|
|||
throw new RuntimeException("No EGLSurface - can't make current");
|
||||
}
|
||||
synchronized (EglBase.lock) {
|
||||
if (!EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
|
||||
if (!EGL14.eglMakeCurrent(
|
||||
eglConnection.getDisplay(), eglSurface, eglSurface, eglConnection.getContext())) {
|
||||
throw new GLException(EGL14.eglGetError(),
|
||||
"eglMakeCurrent failed: 0x" + Integer.toHexString(EGL14.eglGetError()));
|
||||
}
|
||||
|
@ -184,8 +237,8 @@ class EglBase14Impl implements EglBase14 {
|
|||
@Override
|
||||
public void detachCurrent() {
|
||||
synchronized (EglBase.lock) {
|
||||
if (!EGL14.eglMakeCurrent(
|
||||
eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT)) {
|
||||
if (!EGL14.eglMakeCurrent(eglConnection.getDisplay(), EGL14.EGL_NO_SURFACE,
|
||||
EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT)) {
|
||||
throw new GLException(EGL14.eglGetError(),
|
||||
"eglDetachCurrent failed: 0x" + Integer.toHexString(EGL14.eglGetError()));
|
||||
}
|
||||
|
@ -199,7 +252,7 @@ class EglBase14Impl implements EglBase14 {
|
|||
throw new RuntimeException("No EGLSurface - can't swap buffers");
|
||||
}
|
||||
synchronized (EglBase.lock) {
|
||||
EGL14.eglSwapBuffers(eglDisplay, eglSurface);
|
||||
EGL14.eglSwapBuffers(eglConnection.getDisplay(), eglSurface);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,8 +265,8 @@ class EglBase14Impl implements EglBase14 {
|
|||
synchronized (EglBase.lock) {
|
||||
// See
|
||||
// https://android.googlesource.com/platform/frameworks/native/+/tools_r22.2/opengl/specs/EGL_ANDROID_presentation_time.txt
|
||||
EGLExt.eglPresentationTimeANDROID(eglDisplay, eglSurface, timeStampNs);
|
||||
EGL14.eglSwapBuffers(eglDisplay, eglSurface);
|
||||
EGLExt.eglPresentationTimeANDROID(eglConnection.getDisplay(), eglSurface, timeStampNs);
|
||||
EGL14.eglSwapBuffers(eglConnection.getDisplay(), eglSurface);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue