From f166fe245c9e91e49c07f6aed48fedd5eed6d99b Mon Sep 17 00:00:00 2001 From: Linus Nilsson Date: Fri, 6 Oct 2023 15:10:41 +0200 Subject: [PATCH] Avoid excessive eglMakeCurrent calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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‎ Commit-Queue: Linus Nilsson Reviewed-by: Zoé Lepaul Cr-Commit-Position: refs/heads/main@{#40883} --- .../src/java/org/webrtc/EglBase10Impl.java | 45 ++++++++++++------- .../src/java/org/webrtc/EglBase14Impl.java | 43 ++++++++++++------ 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/sdk/android/src/java/org/webrtc/EglBase10Impl.java b/sdk/android/src/java/org/webrtc/EglBase10Impl.java index 5f3cd82e13..caa10e7e51 100644 --- a/sdk/android/src/java/org/webrtc/EglBase10Impl.java +++ b/sdk/android/src/java/org/webrtc/EglBase10Impl.java @@ -94,6 +94,7 @@ class EglBase10Impl implements EglBase10 { private final EGLDisplay eglDisplay; private final EGLConfig eglConfig; private final RefCountDelegate refCountDelegate; + private EGLSurface currentSurface = EGL10.EGL_NO_SURFACE; public EglConnection(EGLContext sharedContext, int[] configAttributes) { egl = (EGL10) EGLContext.getEGL(); @@ -111,6 +112,7 @@ class EglBase10Impl implements EglBase10 { } egl.eglDestroyContext(eglDisplay, eglContext); egl.eglTerminate(eglDisplay); + currentSurface = EGL10.EGL_NO_SURFACE; }); } @@ -152,6 +154,31 @@ class EglBase10Impl implements EglBase10 { public EGLConfig getConfig() { 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. @@ -339,27 +366,13 @@ class EglBase10Impl implements EglBase10 { if (eglSurface == EGL10.EGL_NO_SURFACE) { throw new RuntimeException("No EGLSurface - can't make current"); } - synchronized (EglBase.lock) { - 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())); - } - } + eglConnection.makeCurrent(eglSurface); } // Detach the current EGL context, so that it can be made current on another thread. @Override public void detachCurrent() { - synchronized (EglBase.lock) { - 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())); - } - } + eglConnection.detachCurrent(); } @Override diff --git a/sdk/android/src/java/org/webrtc/EglBase14Impl.java b/sdk/android/src/java/org/webrtc/EglBase14Impl.java index 4c0a3e9dfa..22cee8668b 100644 --- a/sdk/android/src/java/org/webrtc/EglBase14Impl.java +++ b/sdk/android/src/java/org/webrtc/EglBase14Impl.java @@ -56,6 +56,7 @@ class EglBase14Impl implements EglBase14 { private final EGLDisplay eglDisplay; private final EGLConfig eglConfig; private final RefCountDelegate refCountDelegate; + private EGLSurface currentSurface = EGL14.EGL_NO_SURFACE; public EglConnection(EGLContext sharedContext, int[] configAttributes) { eglDisplay = getEglDisplay(); @@ -73,6 +74,7 @@ class EglBase14Impl implements EglBase14 { } EGL14.eglReleaseThread(); EGL14.eglTerminate(eglDisplay); + currentSurface = EGL14.EGL_NO_SURFACE; }); } @@ -108,6 +110,31 @@ class EglBase14Impl implements EglBase14 { public EGLConfig getConfig() { 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. // `sharedContext` may be null. @@ -224,25 +251,13 @@ class EglBase14Impl implements EglBase14 { if (eglSurface == EGL14.EGL_NO_SURFACE) { throw new RuntimeException("No EGLSurface - can't make current"); } - synchronized (EglBase.lock) { - if (!EGL14.eglMakeCurrent( - eglConnection.getDisplay(), eglSurface, eglSurface, eglConnection.getContext())) { - throw new GLException(EGL14.eglGetError(), - "eglMakeCurrent failed: 0x" + Integer.toHexString(EGL14.eglGetError())); - } - } + eglConnection.makeCurrent(eglSurface); } // Detach the current EGL context, so that it can be made current on another thread. @Override public void detachCurrent() { - synchronized (EglBase.lock) { - 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())); - } - } + eglConnection.detachCurrent(); } @Override