Load ANGLE from APK

Allow using ANGLE for GLES instead of native libraries.

To enable this, we also pass a handle to vendor libEGL
to use in GLES backend.  A new GLAttrib is added to
facilitate this: EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE. To
facilitate this, we are adding eglext_angle.h to the tree
from ANGLE revision: 57ff6f95

If a namespace is provided, it will be used to find ANGLE.
This should be the default route for most applications.
The namespace will point to the system ANGLE unless an update
has been applied, then it will point to the update.

To install system version:
  adb root
  adb shell mkdir -p /system/app/ANGLEPrebuilt
  adb push ANGLEPrebuilt.apk /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk
  adb reboot

To install update version:
  adb install ANGLEPrebuilt.apk

To invoke with APK based apps:
  adb shell settings put global angle_enabled_app <package-name>

Test: Manual (calculator, copyTexImage)

Change-Id: Idf2acb64092fe334fd9394c12b2b2f0acaaa4029
(cherry picked from commit cb2d420c7cc5b0a2a33463a8645709f9d411dcab)
(cherry picked from commit 4dd74eb6f2736adf9df785e2c435abb6351c1dac)
(cherry picked from commit 87503698bb3b50e6bf2745c082058eec4abec1a2)
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index e954b4f..2e01965 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -455,6 +455,50 @@
     return dso;
 }
 
+static void* load_angle_from_namespace(const char* kind, android_namespace_t* ns) {
+    const android_dlextinfo dlextinfo = {
+            .flags = ANDROID_DLEXT_USE_NAMESPACE,
+            .library_namespace = ns,
+    };
+
+    std::string name = std::string("lib") + kind + "_angle.so";
+
+    void* so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+
+    if (so) {
+        ALOGD("dlopen_ext from APK (%s) success at %p", name.c_str(), so);
+        return so;
+    } else {
+        ALOGE("dlopen_ext(\"%s\") failed: %s", name.c_str(), dlerror());
+    }
+
+    return nullptr;
+}
+
+static void* load_angle(const char* kind, android_namespace_t* ns, egl_connection_t* cnx) {
+    // Only attempt to load ANGLE libs
+    if (strcmp(kind, "EGL") != 0 && strcmp(kind, "GLESv2") != 0 && strcmp(kind, "GLESv1_CM") != 0)
+        return nullptr;
+
+    void* so = nullptr;
+    std::string name;
+
+    if (ns) {
+        so = load_angle_from_namespace(kind, ns);
+    }
+
+    if (so) {
+        cnx->useAngle = true;
+        // Find and load vendor libEGL for ANGLE
+        if (!cnx->vendorEGL) {
+            cnx->vendorEGL = load_system_driver("EGL");
+        }
+        return so;
+    }
+
+    return nullptr;
+}
+
 static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = {
     "ro.hardware.egl",
     "ro.board.platform",
@@ -486,10 +530,14 @@
     ATRACE_CALL();
 
     void* dso = nullptr;
+    android_namespace_t* ns = android_getAngleNamespace();
+    dso = load_angle(kind, ns, cnx);
 #ifndef __ANDROID_VNDK__
-    android_namespace_t* ns = android_getDriverNamespace();
-    if (ns) {
-        dso = load_updated_driver(kind, ns);
+    if (!dso) {
+        ns = android_getDriverNamespace();
+        if (ns) {
+            dso = load_updated_driver(kind, ns);
+        }
     }
 #endif
     if (!dso) {
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index d16d33a..10a097a 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -21,6 +21,7 @@
 
 #include "../egl_impl.h"
 
+#include <EGL/eglext_angle.h>
 #include <private/EGL/display.h>
 
 #include "egl_cache.h"
@@ -121,6 +122,38 @@
     return sDisplay[uintptr_t(disp)].getDisplay(disp);
 }
 
+EGLDisplay getDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx) {
+    EGLDisplay dpy = EGL_NO_DISPLAY;
+
+    // Locally define this until EGL 1.5 is supported
+    typedef EGLDisplay (*PFNEGLGETPLATFORMDISPLAYPROC)(EGLenum platform, void* native_display,
+                                                       const EGLAttrib* attrib_list);
+
+    PFNEGLGETPLATFORMDISPLAYPROC eglGetPlatformDisplay =
+            reinterpret_cast<PFNEGLGETPLATFORMDISPLAYPROC>(
+                    cnx->egl.eglGetProcAddress("eglGetPlatformDisplay"));
+
+    if (eglGetPlatformDisplay) {
+        intptr_t vendorEGL = (intptr_t)cnx->vendorEGL;
+
+        EGLAttrib attrs[] = {
+                EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE,
+                EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE, vendorEGL,
+                EGL_NONE // list terminator
+        };
+
+        // Initially, request the default display type
+        dpy = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
+                                    reinterpret_cast<void*>(EGL_DEFAULT_DISPLAY), attrs);
+
+    } else {
+        ALOGE("eglGetDisplay(%p) failed: Unable to look up eglGetPlatformDisplay from ANGLE",
+              display);
+    }
+
+    return dpy;
+}
+
 EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
 
     std::lock_guard<std::mutex> _l(lock);
@@ -131,7 +164,14 @@
 
     egl_connection_t* const cnx = &gEGLImpl;
     if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
-        EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
+        EGLDisplay dpy = EGL_NO_DISPLAY;
+
+        if (cnx->useAngle) {
+            dpy = getDisplayAngle(display, cnx);
+        } else {
+            dpy = cnx->egl.eglGetDisplay(display);
+        }
+
         disp.dpy = dpy;
         if (dpy == EGL_NO_DISPLAY) {
             loader.close(cnx->dso);
diff --git a/opengl/libs/EGL/egldefs.h b/opengl/libs/EGL/egldefs.h
index 299d8f7..2600eb0 100644
--- a/opengl/libs/EGL/egldefs.h
+++ b/opengl/libs/EGL/egldefs.h
@@ -47,6 +47,9 @@
     void*               libEgl;
     void*               libGles1;
     void*               libGles2;
+
+    bool                useAngle;
+    void*               vendorEGL;
 };
 
 // ----------------------------------------------------------------------------