Merge "Adding ANGLE systrace support"
diff --git a/opengl/include/EGL/Platform.h b/opengl/include/EGL/Platform.h
new file mode 100644
index 0000000..624d31f
--- /dev/null
+++ b/opengl/include/EGL/Platform.h
@@ -0,0 +1,329 @@
+//
+// Copyright (c) 2015 The ANGLE 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.
+
+// Platform.h: The public interface ANGLE exposes to the API layer, for
+//   doing platform-specific tasks like gathering data, or for tracing.
+
+#ifndef ANGLE_PLATFORM_H
+#define ANGLE_PLATFORM_H
+
+#include <stdint.h>
+#include <array>
+
+#define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x3482
+
+#if defined(_WIN32)
+#   if !defined(LIBANGLE_IMPLEMENTATION)
+#       define ANGLE_PLATFORM_EXPORT __declspec(dllimport)
+#   else
+#       define ANGLE_PLATFORM_EXPORT __declspec(dllexport)
+#   endif
+#elif defined(__GNUC__) || defined(__clang__)
+#   define ANGLE_PLATFORM_EXPORT __attribute__((visibility ("default")))
+#endif
+#if !defined(ANGLE_PLATFORM_EXPORT)
+#   define ANGLE_PLATFORM_EXPORT
+#endif
+
+#if defined(_WIN32)
+#   define ANGLE_APIENTRY __stdcall
+#else
+#   define ANGLE_APIENTRY
+#endif
+
+namespace angle
+{
+struct WorkaroundsD3D;
+using TraceEventHandle = uint64_t;
+using EGLDisplayType   = void *;
+struct PlatformMethods;
+
+// Use a C-like API to not trigger undefined calling behaviour.
+// Avoid using decltype here to work around sanitizer limitations.
+// TODO(jmadill): Use decltype here if/when UBSAN is fixed.
+
+// System --------------------------------------------------------------
+
+// Wall clock time in seconds since the epoch.
+// TODO(jmadill): investigate using an ANGLE internal time library
+using CurrentTimeFunc = double (*)(PlatformMethods *platform);
+inline double DefaultCurrentTime(PlatformMethods *platform)
+{
+    return 0.0;
+}
+
+// Monotonically increasing time in seconds from an arbitrary fixed point in the past.
+// This function is expected to return at least millisecond-precision values. For this reason,
+// it is recommended that the fixed point be no further in the past than the epoch.
+using MonotonicallyIncreasingTimeFunc = double (*)(PlatformMethods *platform);
+inline double DefaultMonotonicallyIncreasingTime(PlatformMethods *platform)
+{
+    return 0.0;
+}
+
+// Logging ------------------------------------------------------------
+
+// Log an error message within the platform implementation.
+using LogErrorFunc = void (*)(PlatformMethods *platform, const char *errorMessage);
+inline void DefaultLogError(PlatformMethods *platform, const char *errorMessage)
+{
+}
+
+// Log a warning message within the platform implementation.
+using LogWarningFunc = void (*)(PlatformMethods *platform, const char *warningMessage);
+inline void DefaultLogWarning(PlatformMethods *platform, const char *warningMessage)
+{
+}
+
+// Log an info message within the platform implementation.
+using LogInfoFunc = void (*)(PlatformMethods *platform, const char *infoMessage);
+inline void DefaultLogInfo(PlatformMethods *platform, const char *infoMessage)
+{
+}
+
+// Tracing --------
+
+// Get a pointer to the enabled state of the given trace category. The
+// embedder can dynamically change the enabled state as trace event
+// recording is started and stopped by the application. Only long-lived
+// literal strings should be given as the category name. The implementation
+// expects the returned pointer to be held permanently in a local static. If
+// the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
+// addTraceEvent is expected to be called by the trace event macros.
+using GetTraceCategoryEnabledFlagFunc = const unsigned char *(*)(PlatformMethods *platform,
+                                                                 const char *categoryName);
+inline const unsigned char *DefaultGetTraceCategoryEnabledFlag(PlatformMethods *platform,
+                                                               const char *categoryName)
+{
+    return nullptr;
+}
+
+//
+// Add a trace event to the platform tracing system. Depending on the actual
+// enabled state, this event may be recorded or dropped.
+// - phase specifies the type of event:
+//   - BEGIN ('B'): Marks the beginning of a scoped event.
+//   - END ('E'): Marks the end of a scoped event.
+//   - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't
+//     need a matching END event. Instead, at the end of the scope,
+//     updateTraceEventDuration() must be called with the TraceEventHandle
+//     returned from addTraceEvent().
+//   - INSTANT ('I'): Standalone, instantaneous event.
+//   - START ('S'): Marks the beginning of an asynchronous event (the end
+//     event can occur in a different scope or thread). The id parameter is
+//     used to match START/FINISH pairs.
+//   - FINISH ('F'): Marks the end of an asynchronous event.
+//   - COUNTER ('C'): Used to trace integer quantities that change over
+//     time. The argument values are expected to be of type int.
+//   - METADATA ('M'): Reserved for internal use.
+// - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag.
+// - name is the name of the event. Also used to match BEGIN/END and
+//   START/FINISH pairs.
+// - id optionally allows events of the same name to be distinguished from
+//   each other. For example, to trace the construction and destruction of
+//   objects, specify the pointer as the id parameter.
+// - timestamp should be a time value returned from monotonicallyIncreasingTime.
+// - numArgs specifies the number of elements in argNames, argTypes, and
+//   argValues.
+// - argNames is the array of argument names. Use long-lived literal strings
+//   or specify the COPY flag.
+// - argTypes is the array of argument types:
+//   - BOOL (1): bool
+//   - UINT (2): unsigned long long
+//   - INT (3): long long
+//   - DOUBLE (4): double
+//   - POINTER (5): void*
+//   - STRING (6): char* (long-lived null-terminated char* string)
+//   - COPY_STRING (7): char* (temporary null-terminated char* string)
+//   - CONVERTABLE (8): WebConvertableToTraceFormat
+// - argValues is the array of argument values. Each value is the unsigned
+//   long long member of a union of all supported types.
+// - flags can be 0 or one or more of the following, ORed together:
+//   - COPY (0x1): treat all strings (name, argNames and argValues of type
+//     string) as temporary so that they will be copied by addTraceEvent.
+//   - HAS_ID (0x2): use the id argument to uniquely identify the event for
+//     matching with other events of the same name.
+//   - MANGLE_ID (0x4): specify this flag if the id parameter is the value
+//     of a pointer.
+using AddTraceEventFunc = angle::TraceEventHandle (*)(PlatformMethods *platform,
+                                                      char phase,
+                                                      const unsigned char *categoryEnabledFlag,
+                                                      const char *name,
+                                                      unsigned long long id,
+                                                      double timestamp,
+                                                      int numArgs,
+                                                      const char **argNames,
+                                                      const unsigned char *argTypes,
+                                                      const unsigned long long *argValues,
+                                                      unsigned char flags);
+inline angle::TraceEventHandle DefaultAddTraceEvent(PlatformMethods *platform,
+                                                    char phase,
+                                                    const unsigned char *categoryEnabledFlag,
+                                                    const char *name,
+                                                    unsigned long long id,
+                                                    double timestamp,
+                                                    int numArgs,
+                                                    const char **argNames,
+                                                    const unsigned char *argTypes,
+                                                    const unsigned long long *argValues,
+                                                    unsigned char flags)
+{
+    return 0;
+}
+
+// Set the duration field of a COMPLETE trace event.
+using UpdateTraceEventDurationFunc = void (*)(PlatformMethods *platform,
+                                              const unsigned char *categoryEnabledFlag,
+                                              const char *name,
+                                              angle::TraceEventHandle eventHandle);
+inline void DefaultUpdateTraceEventDuration(PlatformMethods *platform,
+                                            const unsigned char *categoryEnabledFlag,
+                                            const char *name,
+                                            angle::TraceEventHandle eventHandle)
+{
+}
+
+// Callbacks for reporting histogram data.
+// CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50
+// would do.
+using HistogramCustomCountsFunc = void (*)(PlatformMethods *platform,
+                                           const char *name,
+                                           int sample,
+                                           int min,
+                                           int max,
+                                           int bucketCount);
+inline void DefaultHistogramCustomCounts(PlatformMethods *platform,
+                                         const char *name,
+                                         int sample,
+                                         int min,
+                                         int max,
+                                         int bucketCount)
+{
+}
+// Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample
+// value.
+using HistogramEnumerationFunc = void (*)(PlatformMethods *platform,
+                                          const char *name,
+                                          int sample,
+                                          int boundaryValue);
+inline void DefaultHistogramEnumeration(PlatformMethods *platform,
+                                        const char *name,
+                                        int sample,
+                                        int boundaryValue)
+{
+}
+// Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets.
+using HistogramSparseFunc = void (*)(PlatformMethods *platform, const char *name, int sample);
+inline void DefaultHistogramSparse(PlatformMethods *platform, const char *name, int sample)
+{
+}
+// Boolean histograms track two-state variables.
+using HistogramBooleanFunc = void (*)(PlatformMethods *platform, const char *name, bool sample);
+inline void DefaultHistogramBoolean(PlatformMethods *platform, const char *name, bool sample)
+{
+}
+
+// Allows us to programatically override ANGLE's default workarounds for testing purposes.
+using OverrideWorkaroundsD3DFunc = void (*)(PlatformMethods *platform,
+                                            angle::WorkaroundsD3D *workaroundsD3D);
+inline void DefaultOverrideWorkaroundsD3D(PlatformMethods *platform,
+                                          angle::WorkaroundsD3D *workaroundsD3D)
+{
+}
+
+// Callback on a successful program link with the program binary. Can be used to store
+// shaders to disk. Keys are a 160-bit SHA-1 hash.
+using ProgramKeyType   = std::array<uint8_t, 20>;
+using CacheProgramFunc = void (*)(PlatformMethods *platform,
+                                  const ProgramKeyType &key,
+                                  size_t programSize,
+                                  const uint8_t *programBytes);
+inline void DefaultCacheProgram(PlatformMethods *platform,
+                                const ProgramKeyType &key,
+                                size_t programSize,
+                                const uint8_t *programBytes)
+{
+}
+
+// Platform methods are enumerated here once.
+#define ANGLE_PLATFORM_OP(OP)                                    \
+    OP(currentTime, CurrentTime)                                 \
+    OP(monotonicallyIncreasingTime, MonotonicallyIncreasingTime) \
+    OP(logError, LogError)                                       \
+    OP(logWarning, LogWarning)                                   \
+    OP(logInfo, LogInfo)                                         \
+    OP(getTraceCategoryEnabledFlag, GetTraceCategoryEnabledFlag) \
+    OP(addTraceEvent, AddTraceEvent)                             \
+    OP(updateTraceEventDuration, UpdateTraceEventDuration)       \
+    OP(histogramCustomCounts, HistogramCustomCounts)             \
+    OP(histogramEnumeration, HistogramEnumeration)               \
+    OP(histogramSparse, HistogramSparse)                         \
+    OP(histogramBoolean, HistogramBoolean)                       \
+    OP(overrideWorkaroundsD3D, OverrideWorkaroundsD3D)           \
+    OP(cacheProgram, CacheProgram)
+
+#define ANGLE_PLATFORM_METHOD_DEF(Name, CapsName) CapsName##Func Name = Default##CapsName;
+
+struct ANGLE_PLATFORM_EXPORT PlatformMethods
+{
+    PlatformMethods() {}
+
+    // User data pointer for any implementation specific members. Put it at the start of the
+    // platform structure so it doesn't become overwritten if one version of the platform
+    // adds or removes new members.
+    void *context = 0;
+
+    ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF);
+};
+
+#undef ANGLE_PLATFORM_METHOD_DEF
+
+// Subtract one to account for the context pointer.
+constexpr unsigned int g_NumPlatformMethods = (sizeof(PlatformMethods) / sizeof(uintptr_t)) - 1;
+
+#define ANGLE_PLATFORM_METHOD_STRING(Name) #Name
+#define ANGLE_PLATFORM_METHOD_STRING2(Name, CapsName) ANGLE_PLATFORM_METHOD_STRING(Name),
+
+constexpr const char *const g_PlatformMethodNames[g_NumPlatformMethods] = {
+    ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_STRING2)};
+
+#undef ANGLE_PLATFORM_METHOD_STRING2
+#undef ANGLE_PLATFORM_METHOD_STRING
+
+}  // namespace angle
+
+extern "C" {
+
+// Gets the platform methods on the passed-in EGL display. If the method name signature does not
+// match the compiled signature for this ANGLE, false is returned. On success true is returned.
+// The application should set any platform methods it cares about on the returned pointer.
+// If display is not valid, behaviour is undefined.
+
+ANGLE_PLATFORM_EXPORT bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display,
+                                                                  const char *const methodNames[],
+                                                                  unsigned int methodNameCount,
+                                                                  void *context,
+                                                                  void *platformMethodsOut);
+
+// Sets the platform methods back to their defaults.
+// If display is not valid, behaviour is undefined.
+ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display);
+
+}  // extern "C"
+
+namespace angle
+{
+typedef bool(ANGLE_APIENTRY *GetDisplayPlatformFunc)(angle::EGLDisplayType,
+                                                     const char *const *,
+                                                     unsigned int,
+                                                     void *,
+                                                     void *);
+typedef void(ANGLE_APIENTRY *ResetDisplayPlatformFunc)(angle::EGLDisplayType);
+}  // namespace angle
+
+// This function is not exported
+angle::PlatformMethods *ANGLEPlatformCurrent();
+
+#endif // ANGLE_PLATFORM_H
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index d43c164..2a6dee4 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -143,6 +143,7 @@
         "EGL/egl.cpp",
         "EGL/eglApi.cpp",
         "EGL/Loader.cpp",
+        "EGL/egl_angle_platform.cpp",
     ],
     shared_libs: [
         "libvndksupport",
diff --git a/opengl/libs/EGL/egl_angle_platform.cpp b/opengl/libs/EGL/egl_angle_platform.cpp
new file mode 100644
index 0000000..7e0175a
--- /dev/null
+++ b/opengl/libs/EGL/egl_angle_platform.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined(__ANDROID__)
+
+#include "egl_angle_platform.h"
+#include <time.h>
+
+#include <log/log.h>
+
+namespace angle {
+
+GetDisplayPlatformFunc AnglePlatformImpl::angleGetDisplayPlatform = nullptr;
+ResetDisplayPlatformFunc AnglePlatformImpl::angleResetDisplayPlatform = nullptr;
+// Initialize start time
+time_t AnglePlatformImpl::startTime = time(nullptr);
+
+void AnglePlatformImpl::assignAnglePlatformMethods(PlatformMethods* platformMethods) {
+    platformMethods->addTraceEvent = addTraceEvent;
+    platformMethods->getTraceCategoryEnabledFlag = getTraceCategoryEnabledFlag;
+    platformMethods->monotonicallyIncreasingTime = monotonicallyIncreasingTime;
+    platformMethods->logError = logError;
+    platformMethods->logWarning = logWarning;
+    platformMethods->logInfo = logInfo;
+}
+
+const unsigned char* AnglePlatformImpl::getTraceCategoryEnabledFlag(PlatformMethods* /*platform*/,
+                                                                    const char* /*categoryName*/) {
+    // Returning ptr to 'g' (non-zero) to ALWAYS enable tracing initially.
+    // This ptr is what will be passed into "category_group_enabled" of addTraceEvent
+    static const unsigned char traceEnabled = 'g';
+    return &traceEnabled;
+}
+
+double AnglePlatformImpl::monotonicallyIncreasingTime(PlatformMethods* /*platform*/) {
+    return difftime(time(nullptr), startTime);
+}
+
+void AnglePlatformImpl::logError(PlatformMethods* /*platform*/, const char* errorMessage) {
+    ALOGE("ANGLE Error:%s", errorMessage);
+}
+
+void AnglePlatformImpl::logWarning(PlatformMethods* /*platform*/, const char* warningMessage) {
+    ALOGW("ANGLE Warn:%s", warningMessage);
+}
+
+void AnglePlatformImpl::logInfo(PlatformMethods* /*platform*/, const char* infoMessage) {
+    ALOGD("ANGLE Info:%s", infoMessage);
+}
+
+TraceEventHandle AnglePlatformImpl::addTraceEvent(
+        PlatformMethods* /**platform*/, char phase, const unsigned char* /*category_group_enabled*/,
+        const char* name, unsigned long long /*id*/, double /*timestamp*/, int /*num_args*/,
+        const char** /*arg_names*/, const unsigned char* /*arg_types*/,
+        const unsigned long long* /*arg_values*/, unsigned char /*flags*/) {
+    switch (phase) {
+        case 'B': {
+            ATRACE_BEGIN(name);
+            break;
+        }
+        case 'E': {
+            ATRACE_END();
+            break;
+        }
+        case 'I': {
+            ATRACE_NAME(name);
+            break;
+        }
+        default:
+            // Could handle other event types here
+            break;
+    }
+    // Return any non-zero handle to avoid assert in ANGLE
+    TraceEventHandle result = 1.0;
+    return result;
+}
+
+}; // namespace angle
+
+#endif // __ANDROID__
diff --git a/opengl/libs/EGL/egl_angle_platform.h b/opengl/libs/EGL/egl_angle_platform.h
new file mode 100644
index 0000000..7c6c8ed
--- /dev/null
+++ b/opengl/libs/EGL/egl_angle_platform.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#if defined(__ANDROID__)
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#include <EGL/Platform.h>
+#pragma GCC diagnostic pop
+
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include "egl_trace.h"
+
+namespace angle {
+
+class AnglePlatformImpl {
+public:
+    static void assignAnglePlatformMethods(PlatformMethods* platformMethods);
+    static GetDisplayPlatformFunc angleGetDisplayPlatform;
+    static ResetDisplayPlatformFunc angleResetDisplayPlatform;
+
+private:
+    static time_t startTime;
+    static const unsigned char* getTraceCategoryEnabledFlag(PlatformMethods* /*platform*/,
+                                                            const char* /*categoryName*/);
+    static double monotonicallyIncreasingTime(PlatformMethods* /*platform*/);
+    static void logError(PlatformMethods* /*platform*/, const char* errorMessage);
+    static void logWarning(PlatformMethods* /*platform*/, const char* warningMessage);
+    static void logInfo(PlatformMethods* /*platform*/, const char* infoMessage);
+    static TraceEventHandle addTraceEvent(PlatformMethods* /**platform*/, char phase,
+                                          const unsigned char* /*category_group_enabled*/,
+                                          const char* name, unsigned long long /*id*/,
+                                          double /*timestamp*/, int /*num_args*/,
+                                          const char** /*arg_names*/,
+                                          const unsigned char* /*arg_types*/,
+                                          const unsigned long long* /*arg_values*/,
+                                          unsigned char /*flags*/);
+};
+
+}; // namespace angle
+
+#endif // __ANDROID__
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index d1635b7..d452a6c 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -24,12 +24,16 @@
 #include <EGL/eglext_angle.h>
 #include <private/EGL/display.h>
 
+#include <cutils/properties.h>
+#include "Loader.h"
+#include "egl_angle_platform.h"
 #include "egl_cache.h"
 #include "egl_object.h"
 #include "egl_tls.h"
-#include "egl_trace.h"
-#include "Loader.h"
-#include <cutils/properties.h>
+
+#include <android/dlext.h>
+#include <dlfcn.h>
+#include <graphicsenv/GraphicsEnv.h>
 
 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <configstore/Utils.h>
@@ -196,6 +200,43 @@
     attrs.push_back(EGL_FALSE);
 }
 
+// Initialize function ptrs for ANGLE PlatformMethods struct, used for systrace
+bool initializeAnglePlatform(EGLDisplay dpy) {
+    // Since we're inside libEGL, use dlsym to lookup fptr for ANGLEGetDisplayPlatform
+    android_namespace_t* ns = android_getAngleNamespace();
+    const android_dlextinfo dlextinfo = {
+            .flags = ANDROID_DLEXT_USE_NAMESPACE,
+            .library_namespace = ns,
+    };
+    void* so = android_dlopen_ext("libEGL_angle.so", RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+    angle::AnglePlatformImpl::angleGetDisplayPlatform =
+            reinterpret_cast<angle::GetDisplayPlatformFunc>(dlsym(so, "ANGLEGetDisplayPlatform"));
+
+    if (!angle::AnglePlatformImpl::angleGetDisplayPlatform) {
+        ALOGE("dlsym lookup of ANGLEGetDisplayPlatform in libEGL_angle failed!");
+        return false;
+    }
+
+    angle::AnglePlatformImpl::angleResetDisplayPlatform =
+            reinterpret_cast<angle::ResetDisplayPlatformFunc>(
+                    eglGetProcAddress("ANGLEResetDisplayPlatform"));
+
+    angle::PlatformMethods* platformMethods = nullptr;
+    if (!((angle::AnglePlatformImpl::angleGetDisplayPlatform)(dpy, angle::g_PlatformMethodNames,
+                                                              angle::g_NumPlatformMethods, nullptr,
+                                                              &platformMethods))) {
+        ALOGE("ANGLEGetDisplayPlatform call failed!");
+        return false;
+    }
+    if (platformMethods) {
+        angle::AnglePlatformImpl::assignAnglePlatformMethods(platformMethods);
+    } else {
+        ALOGE("In initializeAnglePlatform() platformMethods struct ptr is NULL. Not assigning "
+              "tracing function ptrs!");
+    }
+    return true;
+}
+
 static EGLDisplay getDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx) {
     EGLDisplay dpy = EGL_NO_DISPLAY;
 
@@ -216,6 +257,10 @@
                                     reinterpret_cast<void*>(EGL_DEFAULT_DISPLAY), attrs.data());
         if (dpy == EGL_NO_DISPLAY) {
             ALOGE("eglGetPlatformDisplay failed!");
+        } else {
+            if (!initializeAnglePlatform(dpy)) {
+                ALOGE("initializeAnglePlatform failed!");
+            }
         }
     } else {
         ALOGE("eglGetDisplay(%p) failed: Unable to look up eglGetPlatformDisplay from ANGLE",
@@ -417,6 +462,10 @@
 
         egl_connection_t* const cnx = &gEGLImpl;
         if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
+            // If we're using ANGLE reset any custom DisplayPlatform
+            if (cnx->useAngle && angle::AnglePlatformImpl::angleResetDisplayPlatform) {
+                (angle::AnglePlatformImpl::angleResetDisplayPlatform)(disp.dpy);
+            }
             if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
                 ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
                         egl_tls_t::egl_strerror(cnx->egl.eglGetError()));