Add displayPresentTime to getFrameTimestamps

Makes HWC1 use displayRetireTime and HWC2 use
displayPresentTime.

Properly takes into account if HWC2On1Adapter is used.

Returns whether present or retire is supported via
eglQueryTimestampSupportedANDROID, which uses a
cached answer in Surface.

Surface::getFrameTimestamps returns with an error
if the caller requests an unsupported timestamp.

Test: adb shell /data/nativetest/libgui_test/libgui_test
--gtest_filter=*GetFrameTimestamps*

Change-Id: Ib91c2d05d7fb5cbf307e2dec1e20e79bcc19d90b
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 6c802cc..b70d5b2 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -636,8 +636,9 @@
 #define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x314F
 #define EGL_COMPOSITION_START_TIME_ANDROID 0x3430
 #define EGL_COMPOSITION_FINISHED_TIME_ANDROID 0x3431
-#define EGL_DISPLAY_RETIRE_TIME_ANDROID 0x3432
-#define EGL_READS_DONE_TIME_ANDROID 0x3433
+#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x3432
+#define EGL_DISPLAY_RETIRE_TIME_ANDROID 0x3433
+#define EGL_READS_DONE_TIME_ANDROID 0x3434
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLAPI EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLint framesAgo, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
 EGLAPI EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 1acdeb08..d5a02e3 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -1204,6 +1204,9 @@
     egl_surface_t * const s = get_surface(surface);
 
     if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) {
+        if (!s->win.get()) {
+            setError(EGL_BAD_SURFACE, EGL_FALSE);
+        }
         int err = native_window_set_auto_refresh(s->win.get(),
             value ? true : false);
         return (err == NO_ERROR) ? EGL_TRUE :
@@ -1212,8 +1215,14 @@
 
 #if ENABLE_EGL_ANDROID_GET_FRAME_TIMESTAMPS
     if (attribute == EGL_TIMESTAMPS_ANDROID) {
+        if (!s->win.get()) {
+            return setError(EGL_BAD_SURFACE, EGL_FALSE);
+        }
         s->enableTimestamps = value;
-        return EGL_TRUE;
+        int err = native_window_enable_frame_timestamps(
+                s->win.get(), value ? true : false);
+        return (err == NO_ERROR) ? EGL_TRUE :
+            setError(EGL_BAD_SURFACE, EGL_FALSE);
     }
 #endif
 
@@ -2021,27 +2030,25 @@
 
     const egl_display_ptr dp = validate_display(dpy);
     if (!dp) {
-        setError(EGL_BAD_DISPLAY, EGL_FALSE);
-        return EGL_FALSE;
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
     }
 
     SurfaceRef _s(dp.get(), surface);
     if (!_s.get()) {
-        setError(EGL_BAD_SURFACE, EGL_FALSE);
-        return EGL_FALSE;
+        return setError(EGL_BAD_SURFACE, EGL_FALSE);
     }
 
     egl_surface_t const * const s = get_surface(surface);
 
     if (!s->enableTimestamps) {
-        setError(EGL_BAD_SURFACE, EGL_FALSE);
-        return EGL_FALSE;
+        return setError(EGL_BAD_SURFACE, EGL_FALSE);
     }
 
     nsecs_t* requestedPresentTime = nullptr;
     nsecs_t* acquireTime = nullptr;
     nsecs_t* refreshStartTime = nullptr;
     nsecs_t* GLCompositionDoneTime = nullptr;
+    nsecs_t* displayPresentTime = nullptr;
     nsecs_t* displayRetireTime = nullptr;
     nsecs_t* releaseTime = nullptr;
 
@@ -2059,6 +2066,9 @@
             case EGL_COMPOSITION_FINISHED_TIME_ANDROID:
                 GLCompositionDoneTime = &values[i];
                 break;
+            case EGL_DISPLAY_PRESENT_TIME_ANDROID:
+                displayPresentTime = &values[i];
+                break;
             case EGL_DISPLAY_RETIRE_TIME_ANDROID:
                 displayRetireTime = &values[i];
                 break;
@@ -2066,21 +2076,27 @@
                 releaseTime = &values[i];
                 break;
             default:
-                setError(EGL_BAD_PARAMETER, EGL_FALSE);
-                return EGL_FALSE;
+                return setError(EGL_BAD_PARAMETER, EGL_FALSE);
         }
     }
 
     status_t ret = native_window_get_frame_timestamps(s->win.get(), framesAgo,
             requestedPresentTime, acquireTime, refreshStartTime,
-            GLCompositionDoneTime, displayRetireTime, releaseTime);
+            GLCompositionDoneTime, displayPresentTime, displayRetireTime,
+            releaseTime);
 
-    if (ret != NO_ERROR) {
-        setError(EGL_BAD_ACCESS, EGL_FALSE);
-        return EGL_FALSE;
+    switch (ret) {
+      case NO_ERROR:
+        return EGL_TRUE;
+      case NAME_NOT_FOUND:
+        return setError(EGL_BAD_ACCESS, EGL_FALSE);
+      case BAD_VALUE:
+        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+      default:
+        // This should not happen. Return an error that is not in the spec
+        // so it's obvious something is very wrong.
+        return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
     }
-
-    return EGL_TRUE;
 }
 
 EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface,
@@ -2090,14 +2106,19 @@
 
     const egl_display_ptr dp = validate_display(dpy);
     if (!dp) {
-        setError(EGL_BAD_DISPLAY, EGL_FALSE);
-        return EGL_FALSE;
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
     }
 
     SurfaceRef _s(dp.get(), surface);
     if (!_s.get()) {
-        setError(EGL_BAD_SURFACE, EGL_FALSE);
-        return EGL_FALSE;
+        return setError(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    egl_surface_t const * const s = get_surface(surface);
+
+    ANativeWindow* window = s->win.get();
+    if (!window) {
+        return setError(EGL_BAD_SURFACE, EGL_FALSE);
     }
 
     switch (timestamp) {
@@ -2106,9 +2127,20 @@
         case EGL_RENDERING_COMPLETE_TIME_ANDROID:
         case EGL_COMPOSITION_START_TIME_ANDROID:
         case EGL_COMPOSITION_FINISHED_TIME_ANDROID:
-        case EGL_DISPLAY_RETIRE_TIME_ANDROID:
         case EGL_READS_DONE_TIME_ANDROID:
             return EGL_TRUE;
+        case EGL_DISPLAY_PRESENT_TIME_ANDROID: {
+            int value = 0;
+            window->query(window,
+                    NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT, &value);
+            return value == 0 ? EGL_FALSE : EGL_TRUE;
+        }
+        case EGL_DISPLAY_RETIRE_TIME_ANDROID: {
+            int value = 0;
+            window->query(window,
+                    NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_RETIRE, &value);
+            return value == 0 ? EGL_FALSE : EGL_TRUE;
+        }
 #endif
         default:
             return EGL_FALSE;
diff --git a/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt b/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt
index 0882cef..b5b6eb5 100644
--- a/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt
+++ b/opengl/specs/EGL_ANDROID_get_frame_timestamps.txt
@@ -38,8 +38,8 @@
     and display of window surfaces.
 
     Some examples of how this might be used:
-        - The display retire time can be used to calculate end-to-end latency of
-          the entire graphics pipeline.
+        - The display present or retire time can be used to calculate end-to-end
+          latency of the entire graphics pipeline.
         - The queue time and rendering complete time can be used to determine
           how long the application's rendering took to complete. Likewise, the
           composition start time and finish time can be used to determine how
@@ -71,8 +71,9 @@
     EGL_RENDERING_COMPLETE_TIME_ANDROID 0x314F
     EGL_COMPOSITION_START_TIME_ANDROID 0x3430
     EGL_COMPOSITION_FINISHED_TIME_ANDROID 0x3431
-    EGL_DISPLAY_RETIRE_TIME_ANDROID 0x3432
-    EGL_READS_DONE_TIME_ANDROID 0x3433
+    EGL_DISPLAY_PRESENT_TIME_ANDROID 0x3432
+    EGL_DISPLAY_RETIRE_TIME_ANDROID 0x3433
+    EGL_READS_DONE_TIME_ANDROID 0x3434
 
 Add to the list of supported tokens for eglSurfaceAttrib in section 3.5.6
 "Surface Attributes", page 43:
@@ -124,12 +125,14 @@
           compositor's rendering work for this frame finished. This will be zero
           if composition was handled by the display and the compositor didn't do
           any rendering.
+        - EGL_DISPLAY_PRESENT_TIME_ANDROID - The time at which this frame
+          started to scan out on the physical display.
         - EGL_DISPLAY_RETIRE_TIME_ANDROID - The time at which this frame was
           replaced by the next frame on-screen.
         - EGL_READS_DONE_TIME_ANDROID - The time at which all reads for the
           purpose of display/composition were completed for this frame.
 
-    Not all implementations may support all off the above timestamp queries. The
+    Not all implementations may support all of the above timestamp queries. The
     function
 
         EGLBoolean eglQueryTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface
@@ -148,4 +151,4 @@
 
 #2 (Brian Anderson, July 22, 2016)
     - Replace EGL_QUEUE_TIME_ANDROID with EGL_REQUESTED_PRESENT_TIME_ANDROID.
-
+    - Add DISPLAY_PRESENT_TIME_ANDROID.
diff --git a/opengl/specs/README b/opengl/specs/README
index 8414d05..1ee99fb 100644
--- a/opengl/specs/README
+++ b/opengl/specs/README
@@ -24,6 +24,7 @@
 0x314F               EGL_RENDERING_COMPLETE_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps)
 0x3430               EGL_COMPOSITION_START_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps)
 0x3431               EGL_COMPOSITION_FINISHED_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps)
-0x3432               EGL_DISPLAY_RETIRE_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps)
-0x3433               EGL_READS_DONE_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps)
-0x3434 - 0x343F      (unused)
+0x3432               EGL_DISPLAY_PRESENT_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps)
+0x3433               EGL_DISPLAY_RETIRE_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps)
+0x3434               EGL_READS_DONE_TIME_ANDROID (EGL_ANDROID_get_frame_timestamps)
+0x3435 - 0x343F      (unused)