Merge "sdm: Disable VBlank for secondary displays"
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 5dc5e4b..ca2f6ff 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -407,8 +407,7 @@
   uint32_t mmWidth;
   uint32_t mmHeight;
   uint32_t type;
-  uint32_t num_modes;
-  drmModeModeInfo *modes;
+  std::vector<drmModeModeInfo> modes;
   DRMTopology topology;
   std::string panel_name;
   DRMPanelMode panel_mode;
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index 06433e4..2c24001 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -49,13 +49,6 @@
     map_fb_mem_ = true;
   }
 
-  // Enable UBWC for framebuffer
-  if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
-      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
-       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
-    ubwc_for_fb_ = true;
-  }
-
   handles_map_.clear();
   allocator_ = new Allocator();
   allocator_->Init();
diff --git a/libgralloc1/gr_buf_mgr.h b/libgralloc1/gr_buf_mgr.h
index 4476eaf..861a7a7 100644
--- a/libgralloc1/gr_buf_mgr.h
+++ b/libgralloc1/gr_buf_mgr.h
@@ -118,7 +118,6 @@
   std::shared_ptr<Buffer> GetBufferFromHandleLocked(const private_handle_t *hnd);
 
   bool map_fb_mem_ = false;
-  bool ubwc_for_fb_ = false;
   Allocator *allocator_ = NULL;
   std::mutex buffer_lock_;
   std::mutex descriptor_lock_;
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index 0262915..67485f1 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -104,7 +104,7 @@
 }
 
 DisplayError HWTVDRM::GetNumDisplayAttributes(uint32_t *count) {
-  *count = connector_info_.num_modes;
+  *count = UINT32(connector_info_.modes.size());
   if (*count <= 0) {
     return kErrorHardware;
   }
@@ -118,7 +118,7 @@
 }
 
 DisplayError HWTVDRM::SetDisplayAttributes(uint32_t index) {
-  if (index >= connector_info_.num_modes) {
+  if (index >= connector_info_.modes.size()) {
     return kErrorNotSupported;
   }
 
@@ -162,7 +162,7 @@
     format = UINT32(stoi(str4.substr(str4.find(':') + 1)));
   }
 
-  for (size_t idex = 0; idex < connector_info_.num_modes; idex ++) {
+  for (size_t idex = 0; idex < connector_info_.modes.size(); idex ++) {
     if ((height == connector_info_.modes[idex].vdisplay) &&
         (width == connector_info_.modes[idex].hdisplay) &&
         (fps == connector_info_.modes[idex].vrefresh)) {
diff --git a/sdm/libs/core/drm/hw_virtual_drm.cpp b/sdm/libs/core/drm/hw_virtual_drm.cpp
index 8513e82..5ea76b0 100644
--- a/sdm/libs/core/drm/hw_virtual_drm.cpp
+++ b/sdm/libs/core/drm/hw_virtual_drm.cpp
@@ -121,7 +121,7 @@
 }
 
 void HWVirtualDRM::DumpConfigs() {
-  for (uint32_t i = 0; i < (uint32_t)connector_info_.num_modes; i++) {
+  for (uint32_t i = 0; i < (uint32_t)connector_info_.modes.size(); i++) {
   DLOGI(
     "Name: %s\tvref: %d\thdisp: %d\t hsync_s: %d\thsync_e:%d\thtotal: %d\t"
     "vdisp: %d\tvsync_s: %d\tvsync_e: %d\tvtotal: %d\n",
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index 4865e08..eb932e3 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -153,6 +153,9 @@
   if (alloc_type & GRALLOC_USAGE_HW_FB) {
     consumer_usage = GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
   }
+  if (alloc_type & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
+    producer_usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+  }
 
   Perform_(gralloc_device_, GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES, width, height, format,
            producer_usage, consumer_usage, aligned_width, aligned_height, &tile_enabled);
diff --git a/sdm/libs/hwc2/hwc_callbacks.cpp b/sdm/libs/hwc2/hwc_callbacks.cpp
index 48ae398..3be3bf6 100644
--- a/sdm/libs/hwc2/hwc_callbacks.cpp
+++ b/sdm/libs/hwc2/hwc_callbacks.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, 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
@@ -34,22 +34,28 @@
 
 namespace sdm {
 
-void HWCCallbacks::Hotplug(hwc2_display_t display, HWC2::Connection state) {
-  if (hotplug_) {
-    hotplug_(hotplug_data_, display, INT32(state));
+HWC2::Error HWCCallbacks::Hotplug(hwc2_display_t display, HWC2::Connection state) {
+  if (!hotplug_) {
+    return HWC2::Error::NoResources;
   }
+  hotplug_(hotplug_data_, display, INT32(state));
+  return HWC2::Error::None;
 }
 
-void HWCCallbacks::Refresh(hwc2_display_t display) {
-  if (refresh_) {
-    refresh_(refresh_data_, display);
+HWC2::Error HWCCallbacks::Refresh(hwc2_display_t display) {
+  if (!refresh_) {
+    return HWC2::Error::NoResources;
   }
+  refresh_(refresh_data_, display);
+  return HWC2::Error::None;
 }
 
-void HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) {
-  if (vsync_) {
-    vsync_(vsync_data_, display, timestamp);
+HWC2::Error HWCCallbacks::Vsync(hwc2_display_t display, int64_t timestamp) {
+  if (!vsync_) {
+    return HWC2::Error::NoResources;
   }
+  vsync_(vsync_data_, display, timestamp);
+  return HWC2::Error::None;
 }
 
 HWC2::Error HWCCallbacks::Register(HWC2::Callback descriptor, hwc2_callback_data_t callback_data,
diff --git a/sdm/libs/hwc2/hwc_callbacks.h b/sdm/libs/hwc2/hwc_callbacks.h
index 015bf5d..d3f4e52 100644
--- a/sdm/libs/hwc2/hwc_callbacks.h
+++ b/sdm/libs/hwc2/hwc_callbacks.h
@@ -40,9 +40,9 @@
 
 class HWCCallbacks {
  public:
-  void Hotplug(hwc2_display_t display, HWC2::Connection state);
-  void Refresh(hwc2_display_t display);
-  void Vsync(hwc2_display_t display, int64_t timestamp);
+  HWC2::Error Hotplug(hwc2_display_t display, HWC2::Connection state);
+  HWC2::Error Refresh(hwc2_display_t display);
+  HWC2::Error Vsync(hwc2_display_t display, int64_t timestamp);
   HWC2::Error Register(HWC2::Callback, hwc2_callback_data_t callback_data,
                        hwc2_function_pointer_t pointer);
 
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index e2bd805..cf4d1a2 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -1483,10 +1483,13 @@
   int aligned_height;
   uint32_t usage = GRALLOC_USAGE_HW_FB;
   int format = HAL_PIXEL_FORMAT_RGBA_8888;
-  int ubwc_enabled = 0;
+  int ubwc_disabled = 0;
   int flags = 0;
-  HWCDebugHandler::Get()->GetProperty("debug.gralloc.enable_fb_ubwc", &ubwc_enabled);
-  if (ubwc_enabled == 1) {
+
+  // By default UBWC is enabled and below property is global enable/disable for all
+  // buffers allocated through gralloc , including framebuffer targets.
+  HWCDebugHandler::Get()->GetProperty("debug.gralloc.gfx_ubwc_disable", &ubwc_disabled);
+  if (!ubwc_disabled) {
     usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
     flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
   }
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 293ffce..7e99f29 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -502,16 +502,16 @@
   if (!device) {
     return HWC2_ERROR_BAD_DISPLAY;
   }
+  SCOPE_LOCK(hwc_session->callbacks_lock_);
   auto desc = static_cast<HWC2::Callback>(descriptor);
   auto error = hwc_session->callbacks_.Register(desc, callback_data, pointer);
   DLOGD("Registering callback: %s", to_string(desc).c_str());
   if (descriptor == HWC2_CALLBACK_HOTPLUG) {
-    // If primary display (HDMI) is not created yet, wait for it to be hotplugged.
-    if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY]) {
+    if (hwc_session->hwc_display_[HWC_DISPLAY_PRIMARY] && !hwc_session->hdmi_is_primary_) {
       hwc_session->callbacks_.Hotplug(HWC_DISPLAY_PRIMARY, HWC2::Connection::Connected);
     }
   }
-
+  hwc_session->callbacks_lock_.Broadcast();
   return INT32(error);
 }
 
@@ -675,7 +675,7 @@
       }
 
       if (hwc_session->need_invalidate_) {
-        hwc_session->callbacks_.Refresh(display);
+        hwc_session->Refresh(display);
       }
 
       if (hwc_session->color_mgr_) {
@@ -1248,7 +1248,7 @@
 
   switch (pending_action.action) {
     case kInvalidating:
-      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      Refresh(HWC_DISPLAY_PRIMARY);
       break;
     case kEnterQDCMMode:
       ret = color_mgr_->EnableQDCMMode(true, hwc_display_[HWC_DISPLAY_PRIMARY]);
@@ -1259,12 +1259,12 @@
     case kApplySolidFill:
       ret =
           color_mgr_->SetSolidFill(pending_action.params, true, hwc_display_[HWC_DISPLAY_PRIMARY]);
-      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      Refresh(HWC_DISPLAY_PRIMARY);
       break;
     case kDisableSolidFill:
       ret =
           color_mgr_->SetSolidFill(pending_action.params, false, hwc_display_[HWC_DISPLAY_PRIMARY]);
-      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      Refresh(HWC_DISPLAY_PRIMARY);
       break;
     case kSetPanelBrightness:
       brightness_value = reinterpret_cast<int32_t *>(resp_payload.payload);
@@ -1278,7 +1278,7 @@
     case kEnableFrameCapture:
       ret = color_mgr_->SetFrameCapture(pending_action.params, true,
                                         hwc_display_[HWC_DISPLAY_PRIMARY]);
-      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      Refresh(HWC_DISPLAY_PRIMARY);
       break;
     case kDisableFrameCapture:
       ret = color_mgr_->SetFrameCapture(pending_action.params, false,
@@ -1287,7 +1287,7 @@
     case kConfigureDetailedEnhancer:
       ret = color_mgr_->SetDetailedEnhancer(pending_action.params,
                                             hwc_display_[HWC_DISPLAY_PRIMARY]);
-      callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+      Refresh(HWC_DISPLAY_PRIMARY);
       break;
     case kNoAction:
       break;
@@ -1319,7 +1319,7 @@
     DLOGI("Uevent FB0 = %s", uevent_data);
     int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
     if (panel_reset == 0) {
-      callbacks_.Refresh(0);
+      Refresh(0);
       reset_panel_ = true;
     }
   } else if (strcasestr(uevent_data, HWC_UEVENT_DRM_EXT_HOTPLUG)) {
@@ -1445,7 +1445,7 @@
   } while (0);
 
   if (connected) {
-    callbacks_.Refresh(0);
+    Refresh(0);
 
     if (!hdmi_is_primary_) {
       // wait for sufficient time to ensure sufficient resources are available to process new
@@ -1457,8 +1457,8 @@
 
   // notify client
   if (notify_hotplug) {
-    callbacks_.Hotplug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
-                       connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
+    HotPlug(hdmi_is_primary_ ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL,
+            connected ? HWC2::Connection::Connected : HWC2::Connection::Disconnected);
   }
 
   qservice_->onHdmiHotplug(INT(connected));
@@ -1507,4 +1507,22 @@
   return android::NO_ERROR;
 }
 
+void HWCSession::Refresh(hwc2_display_t display) {
+  SCOPE_LOCK(callbacks_lock_);
+  HWC2::Error err = callbacks_.Refresh(display);
+  while (err != HWC2::Error::None) {
+    callbacks_lock_.Wait();
+    err = callbacks_.Refresh(display);
+  }
+}
+
+void HWCSession::HotPlug(hwc2_display_t display, HWC2::Connection state) {
+  SCOPE_LOCK(callbacks_lock_);
+  HWC2::Error err = callbacks_.Hotplug(display, state);
+  while (err != HWC2::Error::None) {
+    callbacks_lock_.Wait();
+    err = callbacks_.Hotplug(display, state);
+  }
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 7d2a30c..288bbba 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -211,6 +211,9 @@
 
   android::status_t SetColorModeById(const android::Parcel *input_parcel);
 
+  void Refresh(hwc2_display_t display);
+  void HotPlug(hwc2_display_t display, HWC2::Connection state);
+
   static Locker locker_;
   CoreInterface *core_intf_ = nullptr;
   HWCDisplay *hwc_display_[HWC_NUM_DISPLAY_TYPES] = {nullptr};
@@ -227,6 +230,7 @@
   qService::QService *qservice_ = nullptr;
   HWCSocketHandler socket_handler_;
   bool hdmi_is_primary_ = false;
+  Locker callbacks_lock_;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index 5cb9cf7..383ec3b 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -208,7 +208,7 @@
   if (hwc_display_[disp_id]) {
     error = hwc_display_[disp_id]->SetActiveDisplayConfig(config);
     if (!error) {
-      callbacks_.Refresh(0);
+      Refresh(0);
     }
   }
 
@@ -312,7 +312,7 @@
 Return<int32_t> HWCSession::refreshScreen() {
   SCOPE_LOCK(locker_);
 
-  callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+  Refresh(HWC_DISPLAY_PRIMARY);
 
   return 0;
 }
@@ -349,7 +349,7 @@
   }
 
   // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
-  callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+  Refresh(HWC_DISPLAY_PRIMARY);
 
   // Wait until partial update control is complete
   int32_t error = locker_.WaitFinite(kPartialUpdateControlTimeoutMs);
@@ -443,7 +443,7 @@
   HWBwModes mode = on > 0 ? kBwCamera : kBwDefault;
 
   // trigger invalidate to apply new bw caps.
-  callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
+  Refresh(HWC_DISPLAY_PRIMARY);
 
   if (core_intf_->SetMaxBandwidthMode(mode) != kErrorNone) {
     return -EINVAL;