Merge "display: Add display specific make include"
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 97660ea..8dcab3a 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.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
@@ -211,6 +211,12 @@
    */
   CRTC_SET_DRAM_IB,
   /*
+   * Op: Sets Rotator BW for inline rotation
+   * Arg: uint32_t - CRTC ID
+   *      uint32_t - rot_bw
+   */
+  CRTC_SET_ROT_PREFILL_BW,
+  /*
    * Op: Sets rotator clock for inline rotation
    * Arg: uint32_t - CRTC ID
    *      uint32_t - rot_clk
@@ -311,6 +317,12 @@
    */
   CONNECTOR_SET_CRTC,
   /*
+   * Op: Sets PP feature
+   * Arg: uint32_t - Connector ID
+   * DRMPPFeatureInfo * - PP feature data pointer
+   */
+   CONNECTOR_SET_POST_PROC,
+  /*
    * Op: Sets connector hdr metadata
    * Arg: uint32_t - Connector ID
    *      drm_msm_ext_hdr_metadata - hdr_metadata
@@ -498,6 +510,7 @@
 struct DRMDisplayToken {
   uint32_t conn_id;
   uint32_t crtc_id;
+  uint32_t crtc_index;
 };
 
 enum DRMPPFeatureID {
@@ -531,6 +544,7 @@
   uint32_t version;
   uint32_t payload_size;
   void *payload;
+  uint32_t object_type;
 };
 
 enum DRMCscType {
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 52bc73e..80e91ca 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -560,6 +560,7 @@
   uint64_t llcc_ib_bps = 0;
   uint64_t dram_ab_bps = 0;
   uint64_t dram_ib_bps = 0;
+  uint64_t rot_prefill_bw_bps = 0;
   uint32_t clock_hz = 0;
   uint32_t rot_clock_hz = 0;
 };
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 383bdba..136168b 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -488,9 +488,11 @@
 
   default:
     DLOGE("Spurious state = %d transition requested.", state);
-    break;
+    return kErrorParameters;
   }
 
+  DisablePartialUpdateOneFrame();
+
   if (error == kErrorNone) {
     active_ = active;
     state_ = state;
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.cpp b/sdm/libs/core/drm/hw_color_manager_drm.cpp
index 7563647..295dafd 100644
--- a/sdm/libs/core/drm/hw_color_manager_drm.cpp
+++ b/sdm/libs/core/drm/hw_color_manager_drm.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
@@ -797,14 +797,43 @@
                                              DRMPPFeatureInfo *out_data) {
   DisplayError ret = kErrorNone;
 #ifdef PP_DRM_ENABLE
+  struct SDEDitherCfg *sde_dither = NULL;
+  struct drm_msm_dither *mdp_dither = NULL;
+
   if (!out_data) {
     DLOGE("Invalid input parameter for dither");
     return kErrorParameters;
   }
 
-  out_data->id = kPPFeaturesMax;
+  sde_dither = (struct SDEDitherCfg *)in_data.GetConfigData();
+  out_data->id = kFeatureDither;
   out_data->type = sde_drm::kPropBlob;
   out_data->version = in_data.feature_version_;
+  out_data->payload_size = sizeof(struct drm_msm_dither);
+
+  if (in_data.enable_flags_ & kOpsDisable) {
+    out_data->payload = NULL;
+    return ret;
+  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
+    out_data->payload = NULL;
+    return kErrorParameters;
+  }
+
+  mdp_dither = new drm_msm_dither();
+  if (!mdp_dither) {
+    DLOGE("Failed to allocate memory for dither");
+    return kErrorMemory;
+  }
+
+  mdp_dither->flags = 0;
+  std::memcpy(mdp_dither->matrix, sde_dither->dither_matrix,
+                sizeof(sde_dither->dither_matrix));
+  mdp_dither->temporal_en = sde_dither->temporal_en;
+  mdp_dither->c0_bitdepth = sde_dither->g_y_depth;
+  mdp_dither->c1_bitdepth = sde_dither->b_cb_depth;
+  mdp_dither->c2_bitdepth = sde_dither->r_cr_depth;
+  mdp_dither->c3_bitdepth = 0;
+  out_data->payload = mdp_dither;
 #endif
   return ret;
 }
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index c734f4c..d5bf482 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.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
@@ -57,6 +57,7 @@
 #include <unordered_map>
 #include <utility>
 #include <vector>
+#include <limits>
 
 #include "hw_device_drm.h"
 #include "hw_info_interface.h"
@@ -737,6 +738,7 @@
     return kErrorUndefined;
   }
 
+  SetFullROI();
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
   int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes */);
@@ -918,14 +920,17 @@
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_LLCC_IB, token_.crtc_id, qos_data.llcc_ib_bps);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_AB, token_.crtc_id, qos_data.dram_ab_bps);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_DRAM_IB, token_.crtc_id, qos_data.dram_ib_bps);
+  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_PREFILL_BW, token_.crtc_id,
+                            qos_data.rot_prefill_bw_bps);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROT_CLK, token_.crtc_id, qos_data.rot_clock_hz);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SECURITY_LEVEL, token_.crtc_id, crtc_security_level);
 
-  DLOGI_IF(kTagDriverConfig, "System Clock=%d Hz, Core: AB=%llu Bps, IB=%llu Bps, " \
-           "LLCC: AB=%llu Bps, IB=%llu Bps, DRAM AB=%llu Bps, IB=%llu Bps Rot Clock=%d",
+  DLOGI_IF(kTagDriverConfig, "%s::%s System Clock=%d Hz, Core: AB=%llu Bps, IB=%llu Bps, " \
+           "LLCC: AB=%llu Bps, IB=%llu Bps, DRAM AB=%llu Bps, IB=%llu Bps, "\
+           "Rot: Bw=%llu Bps, Clock=%d Hz", validate ? "Validate" : "Commit", device_name_,
            qos_data.clock_hz, qos_data.core_ab_bps, qos_data.core_ib_bps, qos_data.llcc_ab_bps,
            qos_data.llcc_ib_bps, qos_data.dram_ab_bps, qos_data.dram_ib_bps,
-           qos_data.rot_clock_hz);
+           qos_data.rot_prefill_bw_bps, qos_data.rot_clock_hz);
 
   // Set refresh rate
   if (vrefresh_) {
@@ -1258,13 +1263,18 @@
 DisplayError HWDeviceDRM::SetPPFeatures(PPFeaturesConfig *feature_list) {
   int ret = 0;
   PPFeatureInfo *feature = NULL;
+  DRMPPFeatureInfo kernel_params = {};
+  bool crtc_feature = true;
 
   while (true) {
-    DRMPPFeatureInfo kernel_params = {};
+    crtc_feature = true;
     ret = feature_list->RetrieveNextFeature(&feature);
     if (ret)
       break;
-
+    kernel_params.id = HWColorManagerDrm::ToDrmFeatureId(feature->feature_id_);
+    drm_mgr_intf_->GetCrtcPPInfo(0, &kernel_params);
+    if (kernel_params.version == std::numeric_limits<uint32_t>::max())
+        crtc_feature = false;
     if (feature) {
       DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
       auto drm_features = DrmPPfeatureMap_.find(feature->feature_id_);
@@ -1279,9 +1289,11 @@
           continue;
         }
         ret = HWColorManagerDrm::GetDrmFeature[drm_feature](*feature, &kernel_params);
-        if (!ret)
-          drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC, token_.crtc_id, &kernel_params);
-        HWColorManagerDrm::FreeDrmFeatureData(&kernel_params);
+      if (!ret && crtc_feature)
+        drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC, token_.crtc_id, &kernel_params);
+      else if (!ret && !crtc_feature)
+        drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POST_PROC, token_.conn_id, &kernel_params);
+      HWColorManagerDrm::FreeDrmFeatureData(&kernel_params);
       }
     }
   }
@@ -1484,8 +1496,7 @@
 }
 
 void HWDeviceDRM::GetDRMDisplayToken(sde_drm::DRMDisplayToken *token) const {
-  token->conn_id = token_.conn_id;
-  token->crtc_id = token_.crtc_id;
+  *token = token_;
 }
 
 void HWDeviceDRM::UpdateMixerAttributes() {
@@ -1549,4 +1560,17 @@
   }
 }
 
+void HWDeviceDRM::SetFullROI() {
+  // Reset the CRTC ROI and connector ROI only for the panel that supports partial update
+  if (!hw_panel_info_.partial_update) {
+    return;
+  }
+  uint32_t index = current_mode_index_;
+  DRMRect crtc_rects = {0, 0, mixer_attributes_.width, mixer_attributes_.height};
+  DRMRect conn_rects = {0, 0, display_attributes_[index].x_pixels,
+                         display_attributes_[index].y_pixels};
+  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id, 1, &crtc_rects);
+  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id, 1, &conn_rects);
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index b08c0e6..3af3b77 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -133,6 +133,7 @@
   bool IsResolutionSwitchEnabled() const { return resolution_switch_enabled_; }
   void SetTopology(sde_drm::DRMTopology drm_topology, HWTopology *hw_topology);
   void SetMultiRectMode(const uint32_t flags, sde_drm::DRMMultiRectMode *target);
+  void SetFullROI();
 
   class Registry {
    public:
diff --git a/sdm/libs/core/drm/hw_events_drm.cpp b/sdm/libs/core/drm/hw_events_drm.cpp
index 86a3f54..4d1eea9 100644
--- a/sdm/libs/core/drm/hw_events_drm.cpp
+++ b/sdm/libs/core/drm/hw_events_drm.cpp
@@ -64,19 +64,18 @@
 
     switch (event_data.event_type) {
       case HWEvent::VSYNC: {
-        if (!is_primary_) {
-          // TODO(user): Once secondary support is added, use a different fd by calling drmOpen
-          break;
-        }
-
         poll_fds_[i].events = POLLIN | POLLPRI | POLLERR;
-        DRMMaster *master = nullptr;
-        int ret = DRMMaster::GetInstance(&master);
-        if (ret < 0) {
-          DLOGE("Failed to acquire DRMMaster instance");
-          return kErrorNotSupported;
+        if (is_primary_) {
+          DRMMaster *master = nullptr;
+          int ret = DRMMaster::GetInstance(&master);
+          if (ret < 0) {
+            DLOGE("Failed to acquire DRMMaster instance");
+            return kErrorNotSupported;
+          }
+          master->GetHandle(&poll_fds_[i].fd);
+        } else {
+          poll_fds_[i].fd = drmOpen("msm_drm", nullptr);
         }
-        master->GetHandle(&poll_fds_[i].fd);
         vsync_index_ = i;
       } break;
       case HWEvent::EXIT: {
@@ -197,11 +196,8 @@
     return kErrorResources;
   }
 
-  if (is_primary_) {
-    RegisterVSync();
-    vsync_registered_ = true;
-  }
-
+  RegisterVSync();
+  vsync_registered_ = true;
   RegisterPanelDead(true);
   RegisterIdleNotify(true);
   RegisterIdlePowerCollapse(true);
@@ -226,9 +222,6 @@
   switch (event) {
     case HWEvent::VSYNC: {
       std::lock_guard<std::mutex> lock(vsync_mutex_);
-      if (!is_primary_) {
-        break;
-      }
       vsync_enabled_ = enable;
       if (vsync_enabled_ && !vsync_registered_) {
         RegisterVSync();
@@ -261,7 +254,9 @@
   for (uint32_t i = 0; i < event_data_list_.size(); i++) {
     switch (event_data_list_[i].event_type) {
       case HWEvent::VSYNC:
-        // TODO(user): close for secondary
+        if (!is_primary_) {
+          Sys::close_(poll_fds_[i].fd);
+        }
         poll_fds_[i].fd = -1;
         break;
       case HWEvent::EXIT:
@@ -347,9 +342,10 @@
 }
 
 DisplayError HWEventsDRM::RegisterVSync() {
-  // TODO(user): For secondary use DRM_VBLANK_HIGH_CRTC_MASK and DRM_VBLANK_HIGH_CRTC_SHIFT
-  drmVBlank vblank{};
-  vblank.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT);
+  drmVBlank vblank {};
+  uint32_t high_crtc = token_.crtc_index << DRM_VBLANK_HIGH_CRTC_SHIFT;
+  vblank.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT |
+                                           (high_crtc & DRM_VBLANK_HIGH_CRTC_MASK));
   vblank.request.sequence = 1;
   // DRM hack to pass in context to unused field signal. Driver will write this to the node being
   // polled on, and will be read as part of drm event handling and sent to handler
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index f1d0d80..245b573 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.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
@@ -37,6 +37,7 @@
 #include <drm_res_mgr.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <string>
 #include <vector>
 #include <map>
@@ -290,5 +291,31 @@
         hdr_metadata_.white_point_x, hdr_metadata_.white_point_y, hdr_metadata_.eotf);
 }
 
+DisplayError HWTVDRM::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
+  DisplayError error = kErrorNone;
+  int fd = -1;
+  char data[kMaxStringLength] = {'\0'};
+
+  snprintf(data, sizeof(data), "/sys/devices/virtual/hdcp/msm_hdcp/min_level_change");
+
+  fd = Sys::open_(data, O_WRONLY);
+  if (fd < 0) {
+    DLOGE("File '%s' could not be opened. errno = %d, desc = %s", data, errno, strerror(errno));
+    return kErrorHardware;
+  }
+
+  snprintf(data, sizeof(data), "%d", min_enc_level);
+
+  ssize_t err = Sys::pwrite_(fd, data, strlen(data), 0);
+  if (err <= 0) {
+    DLOGE("Write failed, Error = %s", strerror(errno));
+    error = kErrorHardware;
+  }
+
+  Sys::close_(fd);
+
+  return error;
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/drm/hw_tv_drm.h b/sdm/libs/core/drm/hw_tv_drm.h
index 5661bc2..49384a2 100644
--- a/sdm/libs/core/drm/hw_tv_drm.h
+++ b/sdm/libs/core/drm/hw_tv_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 met:
@@ -48,6 +48,7 @@
   virtual DisplayError Standby();
   virtual DisplayError Commit(HWLayers *hw_layers);
   virtual void PopulateHWPanelInfo();
+  virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
 
  private:
   DisplayError UpdateHDRMetaData(HWLayers *hw_layers);
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 142b84b..213230f 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -1334,6 +1334,7 @@
       dump_frame_index_++;
     }
   }
+  config_pending_ = false;
 
   geometry_changes_ = GeometryChanges::kNone;
   flush_ = false;
@@ -1940,9 +1941,16 @@
 }
 
 int HWCDisplay::SetActiveDisplayConfig(uint32_t config) {
-  int status = (display_intf_->SetActiveConfig(config) == kErrorNone) ? 0 : -1;
+  if (display_config_ == config) {
+    return 0;
+  }
+  display_config_ = config;
+  config_pending_ = true;
   validated_ = false;
-  return status;
+
+  callbacks_->Refresh(id_);
+
+  return 0;
 }
 
 int HWCDisplay::GetActiveDisplayConfig(uint32_t *config) {
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index a5e1457..3977e73 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.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.
  * Not a Contribution.
  *
  * Copyright 2015 The Android Open Source Project
@@ -150,6 +150,10 @@
   virtual int SetState(bool connected) {
     return kErrorNotSupported;
   }
+  virtual DisplayError Flush() {
+    return kErrorNotSupported;
+  }
+
   int SetPanelBrightness(int level);
   int GetPanelBrightness(int *level);
   int ToggleScreenUpdates(bool enable);
@@ -300,6 +304,8 @@
   HWCToneMapper *tone_mapper_ = nullptr;
   uint32_t num_configs_ = 0;
   int disable_hdr_handling_ = 0;  // disables HDR handling.
+  uint32_t display_config_ = 0;
+  bool config_pending_ = false;
 
  private:
   void DumpInputBuffers(void);
diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp
index 2bc2d18..8e00cfd 100644
--- a/sdm/libs/hwc2/hwc_display_external.cpp
+++ b/sdm/libs/hwc2/hwc_display_external.cpp
@@ -115,6 +115,14 @@
     return status;
   }
 
+  if (config_pending_) {
+    if (display_intf_->SetActiveConfig(display_config_) != kErrorNone) {
+      DLOGW("Invalid display config %d", display_config_);
+      // Reset the display config with active config
+      display_intf_->GetActiveConfig(&display_config_);
+    }
+  }
+
   BuildLayerStack();
 
   if (layer_set_.empty()) {
@@ -278,4 +286,8 @@
   }
 }
 
+DisplayError HWCDisplayExternal::Flush() {
+  return display_intf_->Flush();
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display_external.h b/sdm/libs/hwc2/hwc_display_external.h
index fbee6a3..5eb1704 100644
--- a/sdm/libs/hwc2/hwc_display_external.h
+++ b/sdm/libs/hwc2/hwc_display_external.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
@@ -49,6 +49,7 @@
   virtual HWC2::Error Present(int32_t *out_retire_fence);
   virtual void SetSecureDisplay(bool secure_display_active);
   virtual int SetState(bool connected);
+  virtual DisplayError Flush();
 
  private:
   HWCDisplayExternal(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
index 1f2fdf6..531f209 100644
--- a/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/sdm/libs/hwc2/hwc_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
@@ -178,6 +178,13 @@
     MarkLayersForClientComposition();
   }
 
+  if (config_pending_) {
+    if (display_intf_->SetActiveConfig(display_config_) != kErrorNone) {
+      DLOGW("Invalid display config %d", display_config_);
+      // Reset the display config with active config
+      display_intf_->GetActiveConfig(&display_config_);
+    }
+  }
   // Fill in the remaining blanks in the layers and add them to the SDM layerstack
   BuildLayerStack();
   // Checks and replaces layer stack for solid fill
@@ -210,7 +217,8 @@
     // Avoid flush for Command mode panel.
     DisplayConfigFixedInfo display_config;
     display_intf_->GetConfig(&display_config);
-    flush_ = !display_config.is_cmdmode;
+    flush_ = !(display_config.is_cmdmode && secure_display_active_);
+    validated_ = true;
     return status;
   }
 
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index cfc1cb0..71ca78d 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -731,10 +731,9 @@
   }
 
   int32_t interlaced = 0;
-  bool interlace = layer_buffer->flags.interlace;
-  if (getMetaData(handle, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
-    interlace = interlaced ? true : false;
-  }
+  getMetaData(handle, GET_PP_PARAM_INTERLACED, &interlaced);
+  bool interlace = interlaced ? true : false;
+
   if (interlace != layer_buffer->flags.interlace) {
     DLOGI("Layer buffer interlaced metadata has changed. old=%d, new=%d",
           layer_buffer->flags.interlace, interlace);
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 74ffe38..aed9334 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -944,6 +944,10 @@
   DLOGI("Display = %d", disp);
 
   if (disp == HWC_DISPLAY_EXTERNAL) {
+    DisplayError error = hwc_display_[disp]->Flush();
+    if (error != kErrorNone) {
+        DLOGW("Flush failed. Error = %d", error);
+    }
     HWCDisplayExternal::Destroy(hwc_display_[disp]);
   } else if (disp == HWC_DISPLAY_VIRTUAL) {
     HWCDisplayVirtual::Destroy(hwc_display_[disp]);