Support getNativeEglContext in EglBase10Impl.

Bug: webrtc:12471
Change-Id: Iac969b4985b4db02c18f07c4b5ec2a787e312560
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/207434
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Paulina Hensman <phensman@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33271}
diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn
index ea25065..86bb46c 100644
--- a/sdk/android/BUILD.gn
+++ b/sdk/android/BUILD.gn
@@ -141,10 +141,12 @@
 
     suppressed_configs += [ "//build/config/android:hide_all_but_jni_onload" ]
     configs += [ "//build/config/android:hide_all_but_jni" ]
+    ldflags = [ "-lEGL" ]
 
     deps = [
       ":libjingle_peerconnection_jni",
       ":libjingle_peerconnection_metrics_default_jni",
+      ":video_egl_jni",
       "../../pc:libjingle_peerconnection",
       "../../rtc_base",
     ]
@@ -667,6 +669,17 @@
     absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
   }
 
+  # Sources here require -lEGL linker flag. It is separated from video_jni
+  # target for backwards compatibility.
+  rtc_library("video_egl_jni") {
+    visibility = [ "*" ]
+    sources = [ "src/jni/egl_base_10_impl.cc" ]
+    deps = [
+      ":generated_video_egl_jni",
+      ":native_api_jni",
+    ]
+  }
+
   rtc_library("peerconnection_jni") {
     # Do not depend on this target externally unless you absolute have to. It is
     # made public because we don't have a proper NDK yet. Header APIs here are not
@@ -1218,6 +1231,12 @@
     jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h"
   }
 
+  generate_jni("generated_video_egl_jni") {
+    sources = [ "src/java/org/webrtc/EglBase10Impl.java" ]
+    namespace = "webrtc::jni"
+    jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h"
+  }
+
   generate_jni("generated_libvpx_vp8_jni") {
     sources = [
       "api/org/webrtc/LibvpxVp8Decoder.java",
diff --git a/sdk/android/src/java/org/webrtc/EglBase10Impl.java b/sdk/android/src/java/org/webrtc/EglBase10Impl.java
index 3ae38f0..f512490 100644
--- a/sdk/android/src/java/org/webrtc/EglBase10Impl.java
+++ b/sdk/android/src/java/org/webrtc/EglBase10Impl.java
@@ -39,6 +39,7 @@
 
   // EGL wrapper for an actual EGLContext.
   private static class Context implements EglBase10.Context {
+    private final EGL10 egl;
     private final EGLContext eglContext;
 
     @Override
@@ -48,14 +49,37 @@
 
     @Override
     public long getNativeEglContext() {
-      // TODO(magjed): Implement. There is no easy way of getting the native context for EGL 1.0. We
-      // need to make sure to have an EglSurface, then make the context current using that surface,
-      // and then call into JNI and call the native version of eglGetCurrentContext. Then we need to
-      // restore the state and return the native context.
-      return 0 /* EGL_NO_CONTEXT */;
+      EGLContext previousContext = egl.eglGetCurrentContext();
+      EGLDisplay previousDisplay = egl.eglGetCurrentDisplay();
+      EGLSurface previousDrawSurface = egl.eglGetCurrentSurface(EGL10.EGL_DRAW);
+      EGLSurface previousReadSurface = egl.eglGetCurrentSurface(EGL10.EGL_READ);
+      EGLSurface tempEglSurface = null;
+
+      EGLDisplay defaultDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+
+      try {
+        if (previousContext != eglContext) {
+          int[] surfaceAttribs = {EGL10.EGL_WIDTH, 1, EGL10.EGL_HEIGHT, 1, EGL10.EGL_NONE};
+          EGLConfig eglConfig = getEglConfig(egl, defaultDisplay, EglBase.CONFIG_PIXEL_BUFFER);
+
+          tempEglSurface = egl.eglCreatePbufferSurface(defaultDisplay, eglConfig, surfaceAttribs);
+          if (!egl.eglMakeCurrent(defaultDisplay, tempEglSurface, tempEglSurface, eglContext)) {
+            throw new RuntimeException("Failed to make temporary EGL surface active.");
+          }
+        }
+
+        return nativeGetCurrentNativeEGLContext();
+      } finally {
+        if (tempEglSurface != null) {
+          egl.eglMakeCurrent(
+              previousDisplay, previousDrawSurface, previousReadSurface, previousContext);
+          egl.eglDestroySurface(defaultDisplay, tempEglSurface);
+        }
+      }
     }
 
-    public Context(EGLContext eglContext) {
+    public Context(EGL10 egl, EGLContext eglContext) {
+      this.egl = egl;
       this.eglContext = eglContext;
     }
   }
@@ -64,7 +88,7 @@
   public EglBase10Impl(EGLContext sharedContext, int[] configAttributes) {
     this.egl = (EGL10) EGLContext.getEGL();
     eglDisplay = getEglDisplay();
-    eglConfig = getEglConfig(eglDisplay, configAttributes);
+    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);
@@ -186,7 +210,7 @@
 
   @Override
   public org.webrtc.EglBase.Context getEglBaseContext() {
-    return new Context(eglContext);
+    return new Context(egl, eglContext);
   }
 
   @Override
@@ -294,7 +318,7 @@
   }
 
   // Return an EGLConfig, or die trying.
-  private EGLConfig getEglConfig(EGLDisplay eglDisplay, int[] configAttributes) {
+  private static EGLConfig getEglConfig(EGL10 egl, EGLDisplay eglDisplay, int[] configAttributes) {
     EGLConfig[] configs = new EGLConfig[1];
     int[] numConfigs = new int[1];
     if (!egl.eglChooseConfig(eglDisplay, configAttributes, configs, configs.length, numConfigs)) {
@@ -329,4 +353,6 @@
     }
     return eglContext;
   }
+
+  private static native long nativeGetCurrentNativeEGLContext();
 }
diff --git a/sdk/android/src/jni/egl_base_10_impl.cc b/sdk/android/src/jni/egl_base_10_impl.cc
new file mode 100644
index 0000000..1bbc703
--- /dev/null
+++ b/sdk/android/src/jni/egl_base_10_impl.cc
@@ -0,0 +1,23 @@
+/*
+ *  Copyright 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <EGL/egl.h>
+
+#include "sdk/android/generated_video_egl_jni/EglBase10Impl_jni.h"
+
+namespace webrtc {
+namespace jni {
+
+static jlong JNI_EglBase10Impl_GetCurrentNativeEGLContext(JNIEnv* jni) {
+  return reinterpret_cast<jlong>(eglGetCurrentContext());
+}
+
+}  // namespace jni
+}  // namespace webrtc