Avoid excessive eglMakeCurrent calls

With shared EglConnections each client must ensure their EGLSurface
is made current every time they access the thread. This will lead to
unnecessary eglMakeCurrent calls when the EGLSurface is in fact already
current, such as when the EglConnection only has one client or when one
client accesses the thread without interruption.

Bug: b/217863437
Change-Id: I1b03daec4d5cd43af21fe9c168e3637f676b6fec
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/322322
Reviewed-by: Ranveer Aggarwal‎ <ranvr@webrtc.org>
Commit-Queue: Linus Nilsson <lnilsson@webrtc.org>
Reviewed-by: Zoé Lepaul <xalep@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40883}
This commit is contained in:
Linus Nilsson 2023-10-06 15:10:41 +02:00 committed by WebRTC LUCI CQ
parent 36e4dd2f42
commit f166fe245c
2 changed files with 58 additions and 30 deletions

View file

@ -94,6 +94,7 @@ class EglBase10Impl implements EglBase10 {
private final EGLDisplay eglDisplay; private final EGLDisplay eglDisplay;
private final EGLConfig eglConfig; private final EGLConfig eglConfig;
private final RefCountDelegate refCountDelegate; private final RefCountDelegate refCountDelegate;
private EGLSurface currentSurface = EGL10.EGL_NO_SURFACE;
public EglConnection(EGLContext sharedContext, int[] configAttributes) { public EglConnection(EGLContext sharedContext, int[] configAttributes) {
egl = (EGL10) EGLContext.getEGL(); egl = (EGL10) EGLContext.getEGL();
@ -111,6 +112,7 @@ class EglBase10Impl implements EglBase10 {
} }
egl.eglDestroyContext(eglDisplay, eglContext); egl.eglDestroyContext(eglDisplay, eglContext);
egl.eglTerminate(eglDisplay); egl.eglTerminate(eglDisplay);
currentSurface = EGL10.EGL_NO_SURFACE;
}); });
} }
@ -152,6 +154,31 @@ class EglBase10Impl implements EglBase10 {
public EGLConfig getConfig() { public EGLConfig getConfig() {
return eglConfig; return eglConfig;
} }
public void makeCurrent(EGLSurface eglSurface) {
if (egl.eglGetCurrentContext() == eglContext && currentSurface == eglSurface) {
return;
}
synchronized (EglBase.lock) {
if (!egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
throw new GLException(egl.eglGetError(),
"eglMakeCurrent failed: 0x" + Integer.toHexString(egl.eglGetError()));
}
}
currentSurface = eglSurface;
}
public void detachCurrent() {
synchronized (EglBase.lock) {
if (!egl.eglMakeCurrent(
eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT)) {
throw new GLException(egl.eglGetError(),
"eglDetachCurrent failed: 0x" + Integer.toHexString(egl.eglGetError()));
}
}
currentSurface = EGL10.EGL_NO_SURFACE;
}
} }
// Create a new context with the specified config type, sharing data with sharedContext. // Create a new context with the specified config type, sharing data with sharedContext.
@ -339,27 +366,13 @@ class EglBase10Impl implements EglBase10 {
if (eglSurface == EGL10.EGL_NO_SURFACE) { if (eglSurface == EGL10.EGL_NO_SURFACE) {
throw new RuntimeException("No EGLSurface - can't make current"); throw new RuntimeException("No EGLSurface - can't make current");
} }
synchronized (EglBase.lock) { eglConnection.makeCurrent(eglSurface);
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()));
}
}
} }
// Detach the current EGL context, so that it can be made current on another thread. // Detach the current EGL context, so that it can be made current on another thread.
@Override @Override
public void detachCurrent() { public void detachCurrent() {
synchronized (EglBase.lock) { eglConnection.detachCurrent();
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()));
}
}
} }
@Override @Override

View file

@ -56,6 +56,7 @@ class EglBase14Impl implements EglBase14 {
private final EGLDisplay eglDisplay; private final EGLDisplay eglDisplay;
private final EGLConfig eglConfig; private final EGLConfig eglConfig;
private final RefCountDelegate refCountDelegate; private final RefCountDelegate refCountDelegate;
private EGLSurface currentSurface = EGL14.EGL_NO_SURFACE;
public EglConnection(EGLContext sharedContext, int[] configAttributes) { public EglConnection(EGLContext sharedContext, int[] configAttributes) {
eglDisplay = getEglDisplay(); eglDisplay = getEglDisplay();
@ -73,6 +74,7 @@ class EglBase14Impl implements EglBase14 {
} }
EGL14.eglReleaseThread(); EGL14.eglReleaseThread();
EGL14.eglTerminate(eglDisplay); EGL14.eglTerminate(eglDisplay);
currentSurface = EGL14.EGL_NO_SURFACE;
}); });
} }
@ -108,6 +110,31 @@ class EglBase14Impl implements EglBase14 {
public EGLConfig getConfig() { public EGLConfig getConfig() {
return eglConfig; return eglConfig;
} }
public void makeCurrent(EGLSurface eglSurface) {
if (EGL14.eglGetCurrentContext() == eglContext && currentSurface == eglSurface) {
return;
}
synchronized (EglBase.lock) {
if (!EGL14.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
throw new GLException(EGL14.eglGetError(),
"eglMakeCurrent failed: 0x" + Integer.toHexString(EGL14.eglGetError()));
}
}
currentSurface = eglSurface;
}
public void detachCurrent() {
synchronized (EglBase.lock) {
if (!EGL14.eglMakeCurrent(
eglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT)) {
throw new GLException(EGL14.eglGetError(),
"eglDetachCurrent failed: 0x" + Integer.toHexString(EGL14.eglGetError()));
}
}
currentSurface = EGL14.EGL_NO_SURFACE;
}
} }
// Create a new context with the specified config type, sharing data with sharedContext. // Create a new context with the specified config type, sharing data with sharedContext.
// `sharedContext` may be null. // `sharedContext` may be null.
@ -224,25 +251,13 @@ class EglBase14Impl implements EglBase14 {
if (eglSurface == EGL14.EGL_NO_SURFACE) { if (eglSurface == EGL14.EGL_NO_SURFACE) {
throw new RuntimeException("No EGLSurface - can't make current"); throw new RuntimeException("No EGLSurface - can't make current");
} }
synchronized (EglBase.lock) { eglConnection.makeCurrent(eglSurface);
if (!EGL14.eglMakeCurrent(
eglConnection.getDisplay(), eglSurface, eglSurface, eglConnection.getContext())) {
throw new GLException(EGL14.eglGetError(),
"eglMakeCurrent failed: 0x" + Integer.toHexString(EGL14.eglGetError()));
}
}
} }
// Detach the current EGL context, so that it can be made current on another thread. // Detach the current EGL context, so that it can be made current on another thread.
@Override @Override
public void detachCurrent() { public void detachCurrent() {
synchronized (EglBase.lock) { eglConnection.detachCurrent();
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()));
}
}
} }
@Override @Override