sdm: Prioritize vsync register over commit

Back to back display commits can delay RegisterVsync()
-- Wait for previous retire fence.
   This ensures that driver is flushed.
-- Register for vsync
-- Start commit processing.

Change-Id: Id2838dc8fe54cf4af8032cc794e2a12c0f716b88
CRs-Fixed: 2583241
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index 7228049..3f9e7f6 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -54,6 +54,10 @@
   : DisplayBase(display_id, kBuiltIn, event_handler, kDeviceBuiltIn, buffer_sync_handler,
                 buffer_allocator, comp_manager, hw_info_intf) {}
 
+DisplayBuiltIn::~DisplayBuiltIn() {
+  CloseFd(&previous_retire_fence_);
+}
+
 DisplayError DisplayBuiltIn::Init() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   int32_t disable_defer_power_state = 0;
@@ -213,6 +217,16 @@
     }
   }
 
+  if (vsync_enable_) {
+    DTRACE_BEGIN("RegisterVsync");
+    // wait for previous frame's retire fence to signal.
+    buffer_sync_handler_->SyncWait(previous_retire_fence_);
+
+    // Register for vsync and then commit the frame.
+    hw_events_intf_->SetEventState(HWEvent::VSYNC, true);
+    DTRACE_END();
+  }
+
   error = DisplayBase::Commit(layer_stack);
   if (error != kErrorNone) {
     return error;
@@ -259,6 +273,9 @@
 
   first_cycle_ = false;
 
+  CloseFd(&previous_retire_fence_);
+  previous_retire_fence_ = Sys::dup_(layer_stack->retire_fence_fd);
+
   return error;
 }
 
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index 8494091..ee55bb4 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -58,6 +58,8 @@
   DisplayBuiltIn(int32_t display_id, DisplayEventHandler *event_handler,
                  HWInfoInterface *hw_info_intf, BufferSyncHandler *buffer_sync_handler,
                  BufferAllocator *buffer_allocator, CompManager *comp_manager);
+  virtual ~DisplayBuiltIn();
+
   virtual DisplayError Init();
   virtual DisplayError Deinit();
   virtual DisplayError Prepare(LayerStack *layer_stack);
@@ -123,6 +125,7 @@
   Locker dpps_pu_lock_;
   bool dpps_pu_nofiy_pending_ = false;
   bool first_cycle_ = true;
+  int previous_retire_fence_ = -1;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_events_drm.cpp b/sdm/libs/core/drm/hw_events_drm.cpp
index 25bad21..63e7127 100644
--- a/sdm/libs/core/drm/hw_events_drm.cpp
+++ b/sdm/libs/core/drm/hw_events_drm.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -380,6 +380,7 @@
 }
 
 DisplayError HWEventsDRM::RegisterVSync() {
+  DTRACE_SCOPED();
   drmVBlank vblank {};
   uint32_t high_crtc = token_.crtc_index << DRM_VBLANK_HIGH_CRTC_SHIFT;
   vblank.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT |
@@ -501,6 +502,15 @@
 }
 
 void HWEventsDRM::HandleVSync(char *data) {
+  {
+    std::lock_guard<std::mutex> lock(vsync_mutex_);
+    vsync_registered_ = false;
+    if (vsync_enabled_) {
+      RegisterVSync();
+      vsync_registered_ = true;
+    }
+  }
+
   drmEventContext event = {};
   event.version = DRM_EVENT_CONTEXT_VERSION;
   event.vblank_handler = &HWEventsDRM::VSyncHandlerCallback;
@@ -508,13 +518,6 @@
   if (error != 0) {
     DLOGE("drmHandleEvent failed: %i", error);
   }
-
-  std::lock_guard<std::mutex> lock(vsync_mutex_);
-  vsync_registered_ = false;
-  if (vsync_enabled_) {
-    RegisterVSync();
-    vsync_registered_ = true;
-  }
 }
 
 void HWEventsDRM::HandlePanelDead(char *data) {
@@ -561,6 +564,7 @@
 void HWEventsDRM::VSyncHandlerCallback(int fd, unsigned int sequence, unsigned int tv_sec,
                                        unsigned int tv_usec, void *data) {
   int64_t timestamp = (int64_t)(tv_sec)*1000000000 + (int64_t)(tv_usec)*1000;
+  DTRACE_SCOPED();
   reinterpret_cast<HWEventsDRM *>(data)->event_handler_->VSync(timestamp);
 }