Allow native driver to be ANGLE

There are ANGLE specific behaviors that need to be followed whenever
the driver in use is ANGLE. This change removes those behaviors from
the ANGLE load path and allows them to be applied to the "native"
driver if it is ANGLE.

This change removes the ability to select different ANGLE back-ends.
E.g. debug property: "debug.angle.backend" no longer works.
Only Vulkan will be used. The other back-ends are not used or tested
on Android and would be unusable on a production device where ANGLE
is the one and only OpenGL driver.

Test: atest CtsAngleIntegrationHostTestCases
Bug: b/154237217
Change-Id: Ia792f63d8c7b9411056b9277ff4b37fa566335f5
(cherry picked from commit d1646cfd8599963f1d996477ce13df51bf765745)
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 39bf329..d664e4d 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -271,6 +271,12 @@
     if (!hnd) {
         android::GraphicsEnv::getInstance().setDriverLoaded(android::GpuStatsInfo::Api::API_GL,
                                                             false, systemTime() - openTime);
+    } else {
+        // init_angle_backend will check if loaded driver is ANGLE or not,
+        // will set cnx->useAngle appropriately.
+        // Do this here so that we use ANGLE path when driver is ANGLE (e.g. loaded as native),
+        // not just loading ANGLE as option.
+        init_angle_backend(hnd->dso[0], cnx);
     }
 
     LOG_ALWAYS_FATAL_IF(!hnd,
@@ -311,11 +317,6 @@
     cnx->dso = nullptr;
 
     cnx->useAngle = false;
-
-    if (cnx->vendorEGL) {
-        dlclose(cnx->vendorEGL);
-        cnx->vendorEGL = nullptr;
-    }
 }
 
 void Loader::init_api(void* dso,
@@ -482,7 +483,7 @@
     return dso;
 }
 
-static void* load_angle_from_namespace(const char* kind, android_namespace_t* ns) {
+static void* load_angle(const char* kind, android_namespace_t* ns) {
     const android_dlextinfo dlextinfo = {
             .flags = ANDROID_DLEXT_USE_NAMESPACE,
             .library_namespace = ns,
@@ -502,61 +503,6 @@
     return nullptr;
 }
 
-static void* load_angle(const char* kind, android_namespace_t* ns, egl_connection_t* cnx) {
-    void* so = load_angle_from_namespace(kind, ns);
-
-    if (so) {
-        ALOGV("Loaded ANGLE %s library for '%s' (instead of native)", kind,
-            android::GraphicsEnv::getInstance().getAngleAppName().c_str());
-        cnx->useAngle = true;
-
-        char prop[PROPERTY_VALUE_MAX];
-
-        property_get("debug.hwui.renderer", prop, "UNSET");
-        ALOGV("Skia's renderer set to %s", prop);
-
-        EGLint angleBackendDefault = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
-        property_get("debug.angle.backend", prop, "0");
-        switch (atoi(prop)) {
-            case 1:
-                ALOGV("%s: Requesting OpenGLES back-end", __FUNCTION__);
-                angleBackendDefault = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
-                break;
-            case 2:
-                ALOGV("%s: Requesting Vulkan back-end", __FUNCTION__);
-                angleBackendDefault = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
-                break;
-            default:
-                break;
-        }
-
-        cnx->angleBackend = angleBackendDefault;
-        if (!cnx->vendorEGL && (cnx->angleBackend == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)) {
-            // Find and load vendor libEGL for ANGLE's GL back-end to use.
-            char prop[PROPERTY_VALUE_MAX + 1];
-            for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
-                if (property_get(key, prop, nullptr) <= 0) {
-                    continue;
-                }
-                void* dso = load_system_driver("EGL", prop, true);
-                if (dso) {
-                    cnx->vendorEGL = dso;
-                    break;
-                }
-            }
-            if (!cnx->vendorEGL) {
-                cnx->vendorEGL = load_system_driver("EGL", nullptr, true);
-            }
-        }
-    } else {
-        ALOGV("Loaded native %s library for '%s' (instead of ANGLE)", kind,
-            android::GraphicsEnv::getInstance().getAngleAppName().c_str());
-        cnx->useAngle = false;
-    }
-
-    return so;
-}
-
 static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
     ATRACE_CALL();
     const android_dlextinfo dlextinfo = {
@@ -594,22 +540,37 @@
     driver_t* hnd = nullptr;
 
     // ANGLE doesn't ship with GLES library, and thus we skip GLES driver.
-    void* dso = load_angle("EGL", ns, cnx);
+    void* dso = load_angle("EGL", ns);
     if (dso) {
         initialize_api(dso, cnx, EGL);
         hnd = new driver_t(dso);
 
-        dso = load_angle("GLESv1_CM", ns, cnx);
+        dso = load_angle("GLESv1_CM", ns);
         initialize_api(dso, cnx, GLESv1_CM);
         hnd->set(dso, GLESv1_CM);
 
-        dso = load_angle("GLESv2", ns, cnx);
+        dso = load_angle("GLESv2", ns);
         initialize_api(dso, cnx, GLESv2);
         hnd->set(dso, GLESv2);
     }
     return hnd;
 }
 
+void Loader::init_angle_backend(void* dso, egl_connection_t* cnx) {
+    void* eglCreateDeviceANGLE = nullptr;
+
+    ALOGV("dso: %p", dso);
+    eglCreateDeviceANGLE = dlsym(dso, "eglCreateDeviceANGLE");
+    ALOGV("eglCreateDeviceANGLE: %p", eglCreateDeviceANGLE);
+    if (eglCreateDeviceANGLE) {
+        ALOGV("ANGLE GLES library in use");
+        cnx->useAngle = true;
+    } else {
+        ALOGV("Native GLES library in use");
+        cnx->useAngle = false;
+    }
+}
+
 Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx) {
     ATRACE_CALL();
 #ifndef __ANDROID_VNDK__
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index 6f31ab4..7b2d7c9 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -60,6 +60,7 @@
     driver_t* attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix, const bool exact);
     void unload_system_driver(egl_connection_t* cnx);
     void initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask);
+    void init_angle_backend(void* dso, egl_connection_t* cnx);
 
     static __attribute__((noinline))
     void init_api(void* dso,
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index a58e87c..95c3068 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -133,45 +133,6 @@
     return sDisplay[uintptr_t(disp)].getPlatformDisplay(disp, attrib_list);
 }
 
-static bool addAnglePlatformAttributes(egl_connection_t* const cnx,
-                                       std::vector<EGLAttrib>& attrs) {
-    intptr_t vendorEGL = (intptr_t)cnx->vendorEGL;
-
-    attrs.reserve(4 * 2);
-
-    attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
-    attrs.push_back(cnx->angleBackend);
-
-    switch (cnx->angleBackend) {
-        case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
-            ALOGV("%s: Requesting Vulkan ANGLE back-end", __FUNCTION__);
-            char prop[PROPERTY_VALUE_MAX];
-            property_get("debug.angle.validation", prop, "0");
-            attrs.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE);
-            attrs.push_back(atoi(prop));
-            break;
-        case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
-            ALOGV("%s: Requesting Default ANGLE back-end", __FUNCTION__);
-            break;
-        case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
-            ALOGV("%s: Requesting OpenGL ES ANGLE back-end", __FUNCTION__);
-            // NOTE: This is only valid if the backend is OpenGL
-            attrs.push_back(EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE);
-            attrs.push_back(vendorEGL);
-
-            // Context virtualization is only available on GL back-end.
-            // Needed to support threading with GL back-end
-            attrs.push_back(EGL_PLATFORM_ANGLE_CONTEXT_VIRTUALIZATION_ANGLE);
-            attrs.push_back(EGL_FALSE);
-            break;
-        default:
-            ALOGE("%s: Requesting Unknown (%d) ANGLE back-end", __FUNCTION__, cnx->angleBackend);
-            break;
-    }
-
-    return true;
-}
-
 static EGLDisplay getPlatformDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx,
                                           const EGLAttrib* attrib_list, EGLint* error) {
     EGLDisplay dpy = EGL_NO_DISPLAY;
@@ -186,11 +147,14 @@
             }
         }
 
-        if (!addAnglePlatformAttributes(cnx, attrs)) {
-            ALOGE("eglGetDisplay(%p) failed: Mismatch display request", display);
-            *error = EGL_BAD_PARAMETER;
-            return EGL_NO_DISPLAY;
-        }
+        attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
+        attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
+
+        char prop[PROPERTY_VALUE_MAX];
+        property_get("debug.angle.validation", prop, "0");
+        attrs.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE);
+        attrs.push_back(atoi(prop));
+
         attrs.push_back(EGL_NONE);
 
         dpy = cnx->egl.eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp
index c8840f9..1b75b20 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -721,7 +721,7 @@
 
     // NOTE: When using Vulkan backend, the Vulkan runtime makes all the
     // native_window_* calls, so don't do them here.
-    if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+    if (!cnx->useAngle) {
         int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
         if (result < 0) {
             ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
@@ -740,14 +740,14 @@
     std::vector<AttrType> strippedAttribList;
     if (!processAttributes<AttrType>(dp, window, attrib_list, &colorSpace, &strippedAttribList)) {
         ALOGE("error invalid colorspace: %d", colorSpace);
-        if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+        if (!cnx->useAngle) {
             native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
         }
         return EGL_NO_SURFACE;
     }
     attrib_list = strippedAttribList.data();
 
-    if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+    if (!cnx->useAngle) {
         int err = native_window_set_buffers_format(window, format);
         if (err != 0) {
             ALOGE("error setting native window pixel format: %s (%d)", strerror(-err), err);
@@ -779,7 +779,7 @@
     }
 
     // EGLSurface creation failed
-    if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+    if (!cnx->useAngle) {
         native_window_set_buffers_format(window, 0);
         native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
     }
@@ -1419,7 +1419,7 @@
         }
     }
 
-    if (s->cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+    if (!s->cnx->useAngle) {
         if (!sendSurfaceMetadata(s)) {
             native_window_api_disconnect(s->getNativeWindow(), NATIVE_WINDOW_API_EGL);
             return setError(EGL_BAD_NATIVE_WINDOW, (EGLBoolean)EGL_FALSE);
@@ -1444,7 +1444,7 @@
         androidRect.bottom = y;
         androidRects.push_back(androidRect);
     }
-    if (s->cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+    if (!s->cnx->useAngle) {
         native_window_set_surface_damage(s->getNativeWindow(), androidRects.data(),
                                          androidRects.size());
     }
diff --git a/opengl/libs/EGL/egldefs.h b/opengl/libs/EGL/egldefs.h
index 18a3949..5fbffbd 100644
--- a/opengl/libs/EGL/egldefs.h
+++ b/opengl/libs/EGL/egldefs.h
@@ -82,8 +82,6 @@
 
     bool                systemDriverUnloaded;
     bool                useAngle;       // Was ANGLE successfully loaded
-    EGLint              angleBackend;
-    void*               vendorEGL;
 };
 // clang-format on