Plumb refresh cycle duration up to VK_GOOGLE_display_timing.

Test: Manually tested with a modified cube demo, that reports the refresh
duration returned from this extension.

Change-Id: Ib9499429119e910585a4ee9341c3a2d86a3bdae0
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 0b6a8f7..4be11b4 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -151,6 +151,9 @@
             nsecs_t* outDisplayPresentTime, nsecs_t* outDisplayRetireTime,
             nsecs_t* outDequeueReadyTime, nsecs_t* outReleaseTime);
 
+    status_t getDisplayRefreshCyclePeriod(nsecs_t* outMinRefreshDuration,
+            nsecs_t* outMaxRefreshDuration);
+
     status_t getUniqueId(uint64_t* outId) const;
 
 protected:
@@ -207,6 +210,7 @@
     int dispatchSetAutoRefresh(va_list args);
     int dispatchEnableFrameTimestamps(va_list args);
     int dispatchGetFrameTimestamps(va_list args);
+    int dispatchGetDisplayRefreshCyclePeriod(va_list args);
 
 protected:
     virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index c859828..851a495 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -28,6 +28,7 @@
 
 #include <ui/Fence.h>
 #include <ui/Region.h>
+#include <ui/DisplayStatInfo.h>
 
 #include <gui/IProducerListener.h>
 #include <gui/ISurfaceComposer.h>
@@ -261,6 +262,18 @@
 
     return NO_ERROR;
 }
+status_t Surface::getDisplayRefreshCyclePeriod(nsecs_t* outMinRefreshDuration,
+            nsecs_t* outMaxRefreshDuration) {
+    ATRACE_CALL();
+
+    DisplayStatInfo stats;
+    status_t err = composerService()->getDisplayStats(NULL, &stats);
+
+    *outMinRefreshDuration = stats.vsyncPeriod;
+    *outMaxRefreshDuration = stats.vsyncPeriod;
+
+    return NO_ERROR;
+}
 
 int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
     Surface* c = getSelf(window);
@@ -828,6 +841,9 @@
     case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
         res = dispatchGetFrameTimestamps(args);
         break;
+    case NATIVE_WINDOW_GET_REFRESH_CYCLE_PERIOD:
+        res = dispatchGetDisplayRefreshCyclePeriod(args);
+        break;
     default:
         res = NAME_NOT_FOUND;
         break;
@@ -973,6 +989,13 @@
             outDisplayRetireTime, outDequeueReadyTime, outReleaseTime);
 }
 
+int Surface::dispatchGetDisplayRefreshCyclePeriod(va_list args) {
+    nsecs_t* outMinRefreshDuration = va_arg(args, int64_t*);
+    nsecs_t* outMaxRefreshDuration = va_arg(args, int64_t*);
+    return getDisplayRefreshCyclePeriod(outMinRefreshDuration,
+            outMaxRefreshDuration);
+}
+
 int Surface::connect(int api) {
     static sp<IProducerListener> listener = new DummyProducerListener();
     return connect(api, listener);
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 243ea69..08eee37 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -196,11 +196,22 @@
           num_images(num_images_),
           frame_timestamps_enabled(false) {
         timing.clear();
+        ANativeWindow* window = surface.window.get();
+        int64_t min_rdur;
+        int64_t max_rdur;
+        native_window_get_refresh_cycle_period(
+            window,
+            &min_rdur,
+            &max_rdur);
+        min_refresh_duration = static_cast<uint64_t>(min_rdur);
+        max_refresh_duration = static_cast<uint64_t>(max_rdur);
     }
 
     Surface& surface;
     uint32_t num_images;
     bool frame_timestamps_enabled;
+    uint64_t min_refresh_duration;
+    uint64_t max_refresh_duration;
 
     struct Image {
         Image() : image(VK_NULL_HANDLE), dequeue_fence(-1), dequeued(false) {}
@@ -345,9 +356,7 @@
                                 // timestamps to calculate the info that should
                                 // be reported to the user:
                                 //
-                                // FIXME: GET ACTUAL VALUE RATHER THAN HARD-CODE
-                                // IT:
-                                ti->calculate(16666666);
+                                ti->calculate(swapchain.min_refresh_duration);
                                 num_ready++;
                             }
                             break;
@@ -1274,13 +1283,13 @@
 VKAPI_ATTR
 VkResult GetRefreshCycleDurationGOOGLE(
     VkDevice,
-    VkSwapchainKHR,
+    VkSwapchainKHR swapchain_handle,
     VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) {
+    Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
     VkResult result = VK_SUCCESS;
 
-    // TODO(ianelliott): FULLY IMPLEMENT THIS FUNCTION!!!
-    pDisplayTimingProperties->minRefreshDuration = 16666666;
-    pDisplayTimingProperties->maxRefreshDuration = 16666666;
+    pDisplayTimingProperties->minRefreshDuration = swapchain.min_refresh_duration;
+    pDisplayTimingProperties->maxRefreshDuration = swapchain.max_refresh_duration;
 
     return result;
 }