Merge "sdm: Merge release fence after set power mode"
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 303c89b..1f813ac 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, 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 met:
@@ -388,12 +388,13 @@
   /*! @brief Method to set current state of the display device.
 
     @param[in] state \link DisplayState \endlink
+    @param[in] pointer to release fence
 
     @return \link DisplayError \endlink
 
     @sa SetDisplayState
   */
-  virtual DisplayError SetDisplayState(DisplayState state) = 0;
+  virtual DisplayError SetDisplayState(DisplayState state, int *release_fence) = 0;
 
   /*! @brief Method to set active configuration for variable properties of the display device.
 
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 936c398..3bb3441 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, 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 met:
@@ -433,7 +433,7 @@
   return last_power_mode_;
 }
 
-DisplayError DisplayBase::SetDisplayState(DisplayState state) {
+DisplayError DisplayBase::SetDisplayState(DisplayState state, int *release_fence) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
   bool active = false;
@@ -455,7 +455,7 @@
     break;
 
   case kStateOn:
-    error = hw_intf_->PowerOn();
+    error = hw_intf_->PowerOn(release_fence);
     if (error != kErrorNone) {
       return error;
     }
@@ -471,13 +471,13 @@
     break;
 
   case kStateDoze:
-    error = hw_intf_->Doze();
+    error = hw_intf_->Doze(release_fence);
     active = true;
     last_power_mode_ = kStateDoze;
     break;
 
   case kStateDozeSuspend:
-    error = hw_intf_->DozeSuspend();
+    error = hw_intf_->DozeSuspend(release_fence);
     if (display_type_ != kPrimary) {
       active = true;
     }
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 514f09d..5e697d9 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2018, 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 met:
@@ -62,7 +62,7 @@
   virtual DisplayError GetConfig(DisplayConfigFixedInfo *variable_info);
   virtual DisplayError GetActiveConfig(uint32_t *index);
   virtual DisplayError GetVSyncState(bool *enabled);
-  virtual DisplayError SetDisplayState(DisplayState state);
+  virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
   virtual DisplayError SetActiveConfig(uint32_t index);
   virtual DisplayError SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
     return kErrorNotSupported;
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index 91c0d7d..718dd1e 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, 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 met:
@@ -166,10 +166,10 @@
   return error;
 }
 
-DisplayError DisplayPrimary::SetDisplayState(DisplayState state) {
+DisplayError DisplayPrimary::SetDisplayState(DisplayState state, int *release_fence) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
-  error = DisplayBase::SetDisplayState(state);
+  error = DisplayBase::SetDisplayState(state, release_fence);
   if (error != kErrorNone) {
     return error;
   }
@@ -393,19 +393,26 @@
 
 void DisplayPrimary::ResetPanel() {
   DisplayError status = kErrorNone;
+  int release_fence = -1;
 
   DLOGI("Powering off primary");
-  status = SetDisplayState(kStateOff);
+  status = SetDisplayState(kStateOff, &release_fence);
   if (status != kErrorNone) {
     DLOGE("power-off on primary failed with error = %d", status);
   }
+  if (release_fence >= 0) {
+    ::close(release_fence);
+  }
 
   DLOGI("Restoring power mode on primary");
   DisplayState mode = GetLastPowerMode();
-  status = SetDisplayState(mode);
+  status = SetDisplayState(mode, &release_fence);
   if (status != kErrorNone) {
     DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
   }
+  if (release_fence >= 0) {
+    ::close(release_fence);
+  }
 
   DLOGI("Enabling HWVsync");
   status = SetVSyncState(true);
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index 621906b..21ada7c 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, 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 met:
@@ -44,7 +44,7 @@
   virtual DisplayError Commit(LayerStack *layer_stack);
   virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
   virtual DisplayError DisablePartialUpdateOneFrame();
-  virtual DisplayError SetDisplayState(DisplayState state);
+  virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
   virtual void SetIdleTimeoutMs(uint32_t active_ms);
   virtual DisplayError SetDisplayMode(uint32_t mode);
   virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index d5bf482..d28d911 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -709,7 +709,7 @@
   return kErrorNone;
 }
 
-DisplayError HWDeviceDRM::PowerOn() {
+DisplayError HWDeviceDRM::PowerOn(int *release_fence) {
   DTRACE_SCOPED();
   if (!drm_atomic_intf_) {
     DLOGE("DRM Atomic Interface is null!");
@@ -727,6 +727,7 @@
     DLOGE("Failed with error: %d", ret);
     return kErrorHardware;
   }
+  drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence);
 
   return kErrorNone;
 }
@@ -750,7 +751,7 @@
   return kErrorNone;
 }
 
-DisplayError HWDeviceDRM::Doze() {
+DisplayError HWDeviceDRM::Doze(int *release_fence) {
   DTRACE_SCOPED();
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
@@ -760,10 +761,12 @@
     return kErrorHardware;
   }
 
+  drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence);
+
   return kErrorNone;
 }
 
-DisplayError HWDeviceDRM::DozeSuspend() {
+DisplayError HWDeviceDRM::DozeSuspend(int *release_fence) {
   DTRACE_SCOPED();
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id,
@@ -774,6 +777,8 @@
     return kErrorHardware;
   }
 
+  drm_atomic_intf_->Perform(DRMOps::CRTC_GET_RELEASE_FENCE, token_.crtc_id, release_fence);
+
   return kErrorNone;
 }
 
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 3af3b77..a0f579d 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2018, 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
@@ -67,10 +67,10 @@
   virtual DisplayError SetDisplayAttributes(uint32_t index);
   virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
   virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
-  virtual DisplayError PowerOn();
+  virtual DisplayError PowerOn(int *release_fence);
   virtual DisplayError PowerOff();
-  virtual DisplayError Doze();
-  virtual DisplayError DozeSuspend();
+  virtual DisplayError Doze(int *release_fence);
+  virtual DisplayError DozeSuspend(int *release_fence);
   virtual DisplayError Standby();
   virtual DisplayError Validate(HWLayers *hw_layers);
   virtual DisplayError Commit(HWLayers *hw_layers);
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index 245b573..adf1f1e 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -165,11 +165,11 @@
   return kErrorNone;
 }
 
-DisplayError HWTVDRM::Doze() {
+DisplayError HWTVDRM::Doze(int *release_fence) {
   return kErrorNone;
 }
 
-DisplayError HWTVDRM::DozeSuspend() {
+DisplayError HWTVDRM::DozeSuspend(int *release_fence) {
   return kErrorNone;
 }
 
diff --git a/sdm/libs/core/drm/hw_tv_drm.h b/sdm/libs/core/drm/hw_tv_drm.h
index 49384a2..3e592f9 100644
--- a/sdm/libs/core/drm/hw_tv_drm.h
+++ b/sdm/libs/core/drm/hw_tv_drm.h
@@ -43,8 +43,8 @@
   virtual DisplayError SetDisplayAttributes(uint32_t index);
   virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
   virtual DisplayError PowerOff();
-  virtual DisplayError Doze();
-  virtual DisplayError DozeSuspend();
+  virtual DisplayError Doze(int *release_fence);
+  virtual DisplayError DozeSuspend(int *release_fence);
   virtual DisplayError Standby();
   virtual DisplayError Commit(HWLayers *hw_layers);
   virtual void PopulateHWPanelInfo();
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 2c529ae..1f733a0 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, 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
@@ -155,7 +155,7 @@
   return kErrorNone;
 }
 
-DisplayError HWDevice::PowerOn() {
+DisplayError HWDevice::PowerOn(int *release_fence) {
   DTRACE_SCOPED();
 
   if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_UNBLANK) < 0) {
@@ -174,11 +174,11 @@
   return kErrorNone;
 }
 
-DisplayError HWDevice::Doze() {
+DisplayError HWDevice::Doze(int *release_fence) {
   return kErrorNone;
 }
 
-DisplayError HWDevice::DozeSuspend() {
+DisplayError HWDevice::DozeSuspend(int *release_fence) {
   return kErrorNone;
 }
 
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index f32c5bd..353cce5 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, 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 met:
@@ -70,10 +70,10 @@
   virtual DisplayError SetDisplayAttributes(uint32_t index);
   virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
   virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
-  virtual DisplayError PowerOn();
+  virtual DisplayError PowerOn(int *release_fence);
   virtual DisplayError PowerOff();
-  virtual DisplayError Doze();
-  virtual DisplayError DozeSuspend();
+  virtual DisplayError Doze(int *release_fence);
+  virtual DisplayError DozeSuspend(int *release_fence);
   virtual DisplayError Standby();
   virtual DisplayError Validate(HWLayers *hw_layers);
   virtual DisplayError Commit(HWLayers *hw_layers);
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index 5ee8121..3f3c28e 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2018, 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
@@ -344,7 +344,7 @@
   return kErrorNone;
 }
 
-DisplayError HWPrimary::Doze() {
+DisplayError HWPrimary::Doze(int *release_fence) {
   if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_NORMAL) < 0) {
     IOCTL_LOGE(FB_BLANK_NORMAL, device_type_);
     return kErrorHardware;
@@ -353,7 +353,7 @@
   return kErrorNone;
 }
 
-DisplayError HWPrimary::DozeSuspend() {
+DisplayError HWPrimary::DozeSuspend(int *release_fence) {
   if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_VSYNC_SUSPEND) < 0) {
     IOCTL_LOGE(FB_BLANK_VSYNC_SUSPEND, device_type_);
     return kErrorHardware;
diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h
index 69b5445..c6ca5a9 100644
--- a/sdm/libs/core/fb/hw_primary.h
+++ b/sdm/libs/core/fb/hw_primary.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2016, 2018 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 met:
@@ -46,8 +46,8 @@
   virtual DisplayError SetDisplayAttributes(uint32_t index);
   virtual DisplayError GetConfigIndex(char *mode, uint32_t *index);
   virtual DisplayError PowerOff();
-  virtual DisplayError Doze();
-  virtual DisplayError DozeSuspend();
+  virtual DisplayError Doze(int *release_fence);
+  virtual DisplayError DozeSuspend(int *release_fence);
   virtual DisplayError Validate(HWLayers *hw_layers);
   virtual DisplayError Commit(HWLayers *hw_layers);
   virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index 9bb825e..483a4df 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, 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 met:
@@ -85,10 +85,10 @@
   virtual DisplayError SetDisplayAttributes(uint32_t index) = 0;
   virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes) = 0;
   virtual DisplayError GetConfigIndex(char *mode, uint32_t *index) = 0;
-  virtual DisplayError PowerOn() = 0;
+  virtual DisplayError PowerOn(int *release_fence) = 0;
   virtual DisplayError PowerOff() = 0;
-  virtual DisplayError Doze() = 0;
-  virtual DisplayError DozeSuspend() = 0;
+  virtual DisplayError Doze(int *release_fence) = 0;
+  virtual DisplayError DozeSuspend(int *release_fence) = 0;
   virtual DisplayError Standby() = 0;
   virtual DisplayError Validate(HWLayers *hw_layers) = 0;
   virtual DisplayError Commit(HWLayers *hw_layers) = 0;
diff --git a/sdm/libs/hwc2/display_null.cpp b/sdm/libs/hwc2/display_null.cpp
index 16f4da6..7e52911 100644
--- a/sdm/libs/hwc2/display_null.cpp
+++ b/sdm/libs/hwc2/display_null.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2018, 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
@@ -50,7 +50,7 @@
   return kErrorNone;
 }
 
-DisplayError DisplayNull::SetDisplayState(DisplayState state) {
+DisplayError DisplayNull::SetDisplayState(DisplayState state, int *release_fence) {
   state_ = state;
   return kErrorNone;
 }
diff --git a/sdm/libs/hwc2/display_null.h b/sdm/libs/hwc2/display_null.h
index f6c0dda..bd49a16 100644
--- a/sdm/libs/hwc2/display_null.h
+++ b/sdm/libs/hwc2/display_null.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2018, 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
@@ -44,7 +44,7 @@
   virtual ~DisplayNull() { }
   virtual DisplayError Commit(LayerStack *layer_stack);
   virtual DisplayError GetDisplayState(DisplayState *state);
-  virtual DisplayError SetDisplayState(DisplayState state);
+  virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
   virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info);
   virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info);
   virtual bool IsUnderscanSupported() { return true; }
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 03aa7a1..a1d21d8 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -743,9 +743,10 @@
     default:
       return HWC2::Error::BadParameter;
   }
+  int release_fence = -1;
 
   ATRACE_INT("SetPowerMode ", state);
-  DisplayError error = display_intf_->SetDisplayState(state);
+  DisplayError error = display_intf_->SetDisplayState(state, &release_fence);
   validated_ = false;
 
   if (error == kErrorNone) {
@@ -759,6 +760,20 @@
     return HWC2::Error::BadParameter;
   }
 
+  if (release_fence >= 0) {
+    for (auto hwc_layer : layer_set_) {
+      auto fence = hwc_layer->PopBackReleaseFence();
+      auto merged_fence = -1;
+      if (fence >= 0) {
+        merged_fence = sync_merge("sync_merge", release_fence, fence);
+        ::close(fence);
+      } else {
+        merged_fence = ::dup(release_fence);
+      }
+      hwc_layer->PushBackReleaseFence(merged_fence);
+    }
+    ::close(release_fence);
+  }
   return HWC2::Error::None;
 }
 
@@ -1142,7 +1157,7 @@
     for (uint32_t i = 0; i < *out_num_elements; i++, it++) {
       auto hwc_layer = *it;
       out_layers[i] = hwc_layer->GetId();
-      out_fences[i] = hwc_layer->PopReleaseFence();
+      out_fences[i] = hwc_layer->PopFrontReleaseFence();
     }
   } else {
     *out_num_elements = UINT32(layer_set_.size());
@@ -1313,15 +1328,15 @@
       if (swap_interval_zero_ || layer->flags.single_buffer) {
         close(layer_buffer->release_fence_fd);
       } else if (layer->composition != kCompositionGPU) {
-        hwc_layer->PushReleaseFence(layer_buffer->release_fence_fd);
+        hwc_layer->PushBackReleaseFence(layer_buffer->release_fence_fd);
       } else {
-        hwc_layer->PushReleaseFence(-1);
+        hwc_layer->PushBackReleaseFence(-1);
       }
     } else {
       // In case of flush, we don't return an error to f/w, so it will get a release fence out of
       // the hwc_layer's release fence queue. We should push a -1 to preserve release fence
       // circulation semantics.
-      hwc_layer->PushReleaseFence(-1);
+      hwc_layer->PushBackReleaseFence(-1);
     }
 
     layer_buffer->release_fence_fd = -1;
diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp
index 04595ba..45ed891 100644
--- a/sdm/libs/hwc2/hwc_display_external.cpp
+++ b/sdm/libs/hwc2/hwc_display_external.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2018, 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
@@ -239,9 +239,12 @@
         DLOGW("Set frame buffer config failed. Error = %d", error);
         return -1;
       }
-
+      int release_fence = -1;
       display_null_.GetDisplayState(&state);
-      display_intf_->SetDisplayState(state);
+      display_intf_->SetDisplayState(state, &release_fence);
+      if (release_fence >= 0) {
+        ::close(release_fence);
+      }
       validated_ = false;
 
       SetVsyncEnabled(HWC2::Vsync::Enable);
@@ -253,10 +256,14 @@
     }
   } else {
     if (!display_null_.IsActive()) {
+      int release_fence = -1;
       // Preserve required attributes of HDMI display that surfaceflinger sees.
       // Restore HDMI attributes when display is reconnected.
       display_intf_->GetDisplayState(&state);
-      display_null_.SetDisplayState(state);
+      display_null_.SetDisplayState(state, &release_fence);
+      if (release_fence >= 0) {
+        ::close(release_fence);
+      }
 
       error = display_intf_->GetFrameBufferConfig(&fb_config);
       if (error != kErrorNone) {
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 605b319..4320397 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -170,14 +170,14 @@
   layer_ = new Layer();
   // Fences are deferred, so the first time this layer is presented, return -1
   // TODO(user): Verify that fences are properly obtained on suspend/resume
-  release_fences_.push(-1);
+  release_fences_.push_back(-1);
 }
 
 HWCLayer::~HWCLayer() {
   // Close any fences left for this layer
   while (!release_fences_.empty()) {
     ::close(release_fences_.front());
-    release_fences_.pop();
+    release_fences_.pop_front();
   }
   if (layer_) {
     if (layer_->input_buffer.acquire_fence_fd >= 0) {
@@ -887,14 +887,28 @@
 
   return;
 }
-void HWCLayer::PushReleaseFence(int32_t fence) {
-  release_fences_.push(fence);
+
+void HWCLayer::PushBackReleaseFence(int32_t fence) {
+  release_fences_.push_back(fence);
 }
-int32_t HWCLayer::PopReleaseFence(void) {
+
+int32_t HWCLayer::PopBackReleaseFence() {
   if (release_fences_.empty())
     return -1;
+
+  auto fence = release_fences_.back();
+  release_fences_.pop_back();
+
+  return fence;
+}
+
+int32_t HWCLayer::PopFrontReleaseFence() {
+  if (release_fences_.empty())
+    return -1;
+
   auto fence = release_fences_.front();
-  release_fences_.pop();
+  release_fences_.pop_front();
+
   return fence;
 }
 
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index bbc602e..9226744 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -32,7 +32,7 @@
 #undef HWC2_INCLUDE_STRINGIFICATION
 #undef HWC2_USE_CPP11
 #include <map>
-#include <queue>
+#include <deque>
 #include <set>
 #include "core/buffer_allocator.h"
 #include "hwc_buffer_allocator.h"
@@ -88,8 +88,9 @@
   int32_t GetLayerDataspace() { return dataspace_; }
   uint32_t GetGeometryChanges() { return geometry_changes_; }
   void ResetGeometryChanges() { geometry_changes_ = GeometryChanges::kNone; }
-  void PushReleaseFence(int32_t fence);
-  int32_t PopReleaseFence(void);
+  void PushBackReleaseFence(int32_t fence);
+  int32_t PopBackReleaseFence(void);
+  int32_t PopFrontReleaseFence(void);
   bool ValidateAndSetCSC();
   bool SupportLocalConversion(ColorPrimaries working_primaries);
   void ResetValidation() { needs_validate_ = false; }
@@ -105,7 +106,7 @@
   const hwc2_layer_t id_;
   const hwc2_display_t display_id_;
   static std::atomic<hwc2_layer_t> next_id_;
-  std::queue<int32_t> release_fences_;
+  std::deque<int32_t> release_fences_;
   HWCBufferAllocator *buffer_allocator_ = NULL;
   int32_t dataspace_ =  HAL_DATASPACE_UNKNOWN;
   LayerTransform layer_transform_ = {};