Merge "dal: Validate register power event"
diff --git a/composer/hwc_display.cpp b/composer/hwc_display.cpp
index 8b3c97c..6224edf 100755
--- a/composer/hwc_display.cpp
+++ b/composer/hwc_display.cpp
@@ -1610,8 +1610,8 @@
   layer_stack_.client_incompatible = false;
 
   validate_done_ = true;
-
-  return ((*out_num_types > 0) ? HWC2::Error::HasChanges : HWC2::Error::None);
+  return (((*out_num_types > 0) || (has_client_composition_ && *out_num_requests > 0))
+          ? HWC2::Error::HasChanges : HWC2::Error::None);
 }
 
 HWC2::Error HWCDisplay::AcceptDisplayChanges() {
@@ -1904,12 +1904,6 @@
   flush_ = false;
   skip_commit_ = false;
 
-  if (display_pause_pending_) {
-    DLOGI("Pause display %d-%d", sdm_id_, type_);
-    display_paused_ = true;
-    display_pause_pending_ = false;
-  }
-
   layer_stack_.flags.geometry_changed = false;
   geometry_changes_ = GeometryChanges::kNone;
   flush_ = false;
@@ -2269,6 +2263,10 @@
 int HWCDisplay::SetDisplayStatus(DisplayStatus display_status) {
   int status = 0;
 
+  if (secure_event_ != kSecureEventMax) {
+    DLOGW("SetDisplayStatus is not supported when TUI transition in progress");
+    return -ENOTSUP;
+  }
   switch (display_status) {
     case kDisplayStatusResume:
       display_paused_ = false;
@@ -2373,6 +2371,10 @@
 }
 
 int HWCDisplay::ToggleScreenUpdates(bool enable) {
+  if (secure_event_ != kSecureEventMax) {
+    DLOGW("Toggle screen updates is not supported when TUI transition in progress");
+    return -ENOTSUP;
+  }
   display_paused_ = enable ? false : true;
   callbacks_->Refresh(id_);
   return 0;
@@ -3090,7 +3092,7 @@
       }
       break;
     case kTUITransitionStart:
-      if (secure_event_ != kSecureEventMax) {
+      if (secure_event_ != kTUITransitionPrepare) {
         DLOGE("Invalid TUI transition from %d to %d", secure_event_, secure_event);
         return kErrorParameters;
       }
@@ -3108,11 +3110,17 @@
   return kErrorNone;
 }
 
-DisplayError HWCDisplay::HandleSecureEvent(SecureEvent secure_event, bool *needs_refresh) {
+DisplayError HWCDisplay::HandleSecureEvent(SecureEvent secure_event, bool *needs_refresh,
+                                           bool update_event_only) {
   if (secure_event == secure_event_) {
     return kErrorNone;
   }
 
+  if (update_event_only) {
+    secure_event_ = secure_event;
+    return kErrorNone;
+  }
+
   DisplayError err = ValidateTUITransition(secure_event);
   if (err != kErrorNone) {
     return err;
@@ -3184,6 +3192,9 @@
   pending_cwb_request = !!cwb_buffer_map_.size();
   }
 
+  *needs_refresh = true;
+  display_intf_->HandleCwbTeardown();
+
   if (!pending_cwb_request) {
     dump_frame_count_ = 0;
     dump_frame_index_ = 0;
@@ -3201,13 +3212,8 @@
     output_buffer_base_ = nullptr;
     frame_capture_buffer_queued_ = false;
     frame_capture_status_ = 0;
-    *needs_refresh = false;
-    return kErrorNone;
-  } else {
-    *needs_refresh = true;
-    display_intf_->HandleCwbTeardown();
-    return kErrorNone;
   }
+  return kErrorNone;
 }
 
 void HWCDisplay::MMRMEvent(bool restricted) {
@@ -3279,7 +3285,7 @@
   }
 
   if (secure_event_ != kSecureEventMax) {
-    DLOGE("CWB is not supported as TUI transition is in progress");
+    DLOGW("CWB is not supported as TUI transition is in progress");
     return HWC2::Error::Unsupported;
   }
 
@@ -3360,6 +3366,24 @@
   LayerRect &full_rect = config.cwb_full_rect;
   CwbTapPoint &tap_point = config.tap_point;
 
+  LayerRect full_rect_with_window_rect = full_rect;
+  LayerRect cwb_roi_with_window_rect = roi;
+
+  full_rect_with_window_rect.left += window_rect_.left;
+  full_rect_with_window_rect.top += window_rect_.top;
+  full_rect_with_window_rect.right -= window_rect_.right;
+  full_rect_with_window_rect.bottom -= window_rect_.bottom;
+
+  cwb_roi_with_window_rect.left += window_rect_.left;
+  cwb_roi_with_window_rect.top += window_rect_.top;
+  cwb_roi_with_window_rect.right += window_rect_.left;
+  cwb_roi_with_window_rect.bottom += window_rect_.top;
+
+  if (windowed_display_ && (!(Contains(full_rect_with_window_rect, cwb_roi_with_window_rect)))) {
+    DLOGW("Requested CWB ROI is out of bounds");
+    return HWC2::Error::Unsupported;
+  }
+
   DisplayError error = kErrorNone;
   error = display_intf_->CaptureCwb(output_buffer, config);
   if (error) {
diff --git a/composer/hwc_display.h b/composer/hwc_display.h
index 017c41e..ae98ccb 100644
--- a/composer/hwc_display.h
+++ b/composer/hwc_display.h
@@ -247,7 +247,8 @@
   virtual int Perform(uint32_t operation, ...);
   virtual int HandleSecureSession(const std::bitset<kSecureMax> &secure_sessions,
                                   bool *power_on_pending, bool is_active_secure_display);
-  virtual DisplayError HandleSecureEvent(SecureEvent secure_event, bool *needs_refresh);
+  virtual DisplayError HandleSecureEvent(SecureEvent secure_event, bool *needs_refresh,
+                                         bool update_event_only);
   virtual DisplayError PostHandleSecureEvent(SecureEvent secure_event);
   virtual int GetActiveSecureSession(std::bitset<kSecureMax> *secure_sessions) { return 0; };
   virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height);
diff --git a/composer/hwc_layers.cpp b/composer/hwc_layers.cpp
index c18930d..842269f 100644
--- a/composer/hwc_layers.cpp
+++ b/composer/hwc_layers.cpp
@@ -620,8 +620,16 @@
     return HWC2::Error::BadParameter;
   }
 
+  uint8_t kMaxPlaneAlpha = 255;
   //  Conversion of float alpha in range 0.0 to 1.0 similar to the HWC Adapter
-  uint8_t plane_alpha = static_cast<uint8_t>(std::round(255.0f * alpha));
+  uint8_t plane_alpha = static_cast<uint8_t>(std::round(float(kMaxPlaneAlpha) * alpha));
+
+  //  if alpha lies in the range (0.998, 1), plane_alpha becomes 255 when rounded off,
+  //  while alpha < 1. HWC knows layer as opaque and marks punch hole for that layer in fbt,
+  //  while SF knows it as non-opaque and doesn't create punch hole.
+  if ((plane_alpha == kMaxPlaneAlpha) && (alpha < 1.0f)) {
+    plane_alpha = (kMaxPlaneAlpha - 1);
+  }
 
   if (layer_->plane_alpha != plane_alpha) {
     geometry_changes_ |= kPlaneAlpha;
diff --git a/composer/hwc_session.cpp b/composer/hwc_session.cpp
index 555930f..4d3908e 100644
--- a/composer/hwc_session.cpp
+++ b/composer/hwc_session.cpp
@@ -4372,11 +4372,9 @@
   for (auto &info : map_info) {
     SEQUENCE_WAIT_SCOPE_LOCK(locker_[info.client_id]);
     if (hwc_display_[info.client_id]) {
-      if (info.client_id == target_display) {
-        continue;
-      }
-      if (hwc_display_[info.client_id]->HandleSecureEvent(kTUITransitionPrepare,
-                                                          &needs_refresh) != kErrorNone) {
+      if (hwc_display_[info.client_id]->HandleSecureEvent(kTUITransitionPrepare, &needs_refresh,
+                                                          info.client_id == target_display) !=
+                                                          kErrorNone) {
         return -EINVAL;
       }
     }
@@ -4420,8 +4418,8 @@
   {
     SEQUENCE_WAIT_SCOPE_LOCK(locker_[target_display]);
     if (hwc_display_[target_display]) {
-      if (hwc_display_[target_display]->HandleSecureEvent(kTUITransitionStart,
-                                                          &needs_refresh) != kErrorNone) {
+      if (hwc_display_[target_display]->HandleSecureEvent(kTUITransitionStart, &needs_refresh,
+                                                          false) != kErrorNone) {
         return -EINVAL;
       }
       uint32_t config = 0;
@@ -4481,8 +4479,8 @@
     hwc_display_[target_display]->SetIdleTimeoutMs(idle_time_active_ms_, idle_time_inactive_ms_);
     hwc_display_[target_display]->SetQSyncMode(hwc_display_qsync_[target_display]);
     if (hwc_display_[target_display]) {
-      if (hwc_display_[target_display]->HandleSecureEvent(kTUITransitionEnd,
-                                                          &needs_refresh) != kErrorNone) {
+      if (hwc_display_[target_display]->HandleSecureEvent(kTUITransitionEnd, &needs_refresh,
+                                                          false) != kErrorNone) {
         return -EINVAL;
       }
     } else {
@@ -4537,14 +4535,12 @@
     {
       SEQUENCE_WAIT_SCOPE_LOCK(locker_[info.client_id]);
       if (hwc_display_[info.client_id]) {
-        if (info.client_id == target_display) {
-          continue;
-        }
         if (info.disp_type == kPluggable && pending_hotplug_event_ == kHotPlugEvent) {
           continue;
         }
-        if (hwc_display_[info.client_id]->HandleSecureEvent(kTUITransitionUnPrepare,
-                                                            &needs_refresh) != kErrorNone) {
+        if (hwc_display_[info.client_id]->HandleSecureEvent(kTUITransitionUnPrepare, &needs_refresh,
+                                                            info.client_id == target_display) !=
+                                                            kErrorNone) {
           return -EINVAL;
         }
       }
diff --git a/composer/service.cpp b/composer/service.cpp
index de8c0f5..426a015 100644
--- a/composer/service.cpp
+++ b/composer/service.cpp
@@ -26,6 +26,13 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
+/* Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
@@ -33,6 +40,7 @@
 
 #include "DisplayConfigAIDL.h"
 #include "QtiComposer.h"
+#include "hwc_debugger.h"
 
 using aidl::vendor::qti::hardware::display::config::DisplayConfigAIDL;
 using android::ProcessState;
@@ -46,11 +54,20 @@
 int main(int, char **) {
   ALOGI("Creating Display HW Composer HAL");
 
+  int composer_thread_count = 8;
+  sdm::HWCDebugHandler::Get()->GetProperty(COMPOSER_THREAD_COUNT, &composer_thread_count);
+  if (composer_thread_count < 4) {
+    composer_thread_count = 4;
+  } else if (composer_thread_count > 15) {
+    composer_thread_count = 15;
+  }
+  ALOGI("composer_thread_count: %d", composer_thread_count);
+
   // TODO(user): double-check for SCHED_FIFO logic
   // the conventional HAL might start binder services
   ProcessState::initWithDriver("/dev/vndbinder");
   sp<ProcessState> ps(ProcessState::self());
-  ps->setThreadPoolMaxThreadCount(4);
+  ps->setThreadPoolMaxThreadCount(composer_thread_count);
   ps->startThreadPool();
   ALOGI("ProcessState initialization completed");
 
@@ -73,7 +90,7 @@
   }
 
   ALOGI("Configuring RPC threadpool");
-  configureRpcThreadpool(4, true /*callerWillJoin*/);
+  configureRpcThreadpool(composer_thread_count, true /*callerWillJoin*/);
   ALOGI("Configuring RPC threadpool...done!");
 
   ALOGI("Registering Display HW Composer HAL as a service");
diff --git a/include/display_properties.h b/include/display_properties.h
index 95deb7a..8d33e5a 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -74,6 +74,7 @@
 #define EXTERNAL_ACTION_SAFE_HEIGHT_PROP     DISPLAY_PROP("external_action_safe_height")
 #define FB_WIDTH_PROP                        DISPLAY_PROP("fb_width")
 #define FB_HEIGHT_PROP                       DISPLAY_PROP("fb_height")
+#define COMPOSER_THREAD_COUNT                DISPLAY_PROP("composer_thread_count")
 #define DISABLE_METADATA_DYNAMIC_FPS_PROP    DISPLAY_PROP("disable_metadata_dynamic_fps")
 #define DISABLE_SKIP_VALIDATE_PROP           DISPLAY_PROP("disable_skip_validate")
 #define DISABLE_DESTINATION_SCALER_PROP      DISPLAY_PROP("disable_dest_scaler")
@@ -163,6 +164,7 @@
 #define ANTI_AGING_RECORD_TIMER              DISPLAY_PROP("demura_record_timer")
 #define ANTI_AGING_IDLE_TIMER                DISPLAY_PROP("demura_idle_timer")
 #define ANTI_AGING_MEMORY_SIZE               DISPLAY_PROP("demura_memory_size")
+#define ANTI_AGING_RECALIB_TIMER_DIVIDER     DISPLAY_PROP("demura_recalib_timer_divider")
 
 // PERF hint properties
 #define ENABLE_PERF_HINT_LARGE_COMP_CYCLE    DISPLAY_PROP("enable_perf_hint_large_comp_cycle")
diff --git a/init/init.qti.display_boot.sh b/init/init.qti.display_boot.sh
index 5baeadd..2df8b36 100644
--- a/init/init.qti.display_boot.sh
+++ b/init/init.qti.display_boot.sh
@@ -60,7 +60,10 @@
     #SOC ID for Kalama SG36 is 600
     #SOC ID for Kalama SG p is 601
     case "$soc_hwid" in
-        519|600|601)
+       519|600|601|603|604)
+        #Set property for kalama
+        #SOC ID for QCS Kalama is 603
+        #SOC ID for QCM Kalama is 604
         setprop vendor.display.enable_fb_scaling 0
         setprop vendor.display.target.version 4
         setprop vendor.gralloc.use_dma_buf_heaps 1
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 75aada6..edcc64a 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -125,6 +125,7 @@
   DisplayError error = kErrorNone;
   hw_panel_info_ = HWPanelInfo();
   hw_intf_->GetHWPanelInfo(&hw_panel_info_);
+  default_panel_mode_ = hw_panel_info_.mode;
   if (hw_info_intf_) {
     hw_info_intf_->GetHWResourceInfo(&hw_resource_info_);
   }
@@ -1968,6 +1969,7 @@
     return error;
   }
 
+  avoid_qsync_mode_change_ = true;
   active_refresh_rate_ = display_attributes.fps;
 
   return ReconfigureDisplay();
@@ -3768,9 +3770,11 @@
   DLOGI("Secure event %d for display %d-%d", secure_event, display_id_, display_type_);
 
   if (secure_event == kTUITransitionStart &&
-      (state_ != kStateOn || (pending_power_state_ != kPowerStateNone))) {
-    DLOGW("Cannot start TUI session when display state is %d or pending_power_state %d",
-          state_, pending_power_state_);
+      (state_ != kStateOn || (pending_power_state_ != kPowerStateNone) ||
+       (hw_panel_info_.mode != default_panel_mode_))) {
+    DLOGW("Cannot start TUI session when display state is %d or pending_power_state %d "
+          "or panel mode is changed; current panel mode = %d, panel mode during bootup = %d",
+           state_, pending_power_state_, hw_panel_info_.mode, default_panel_mode_);
     return kErrorPermission;
   }
   shared_ptr<Fence> release_fence = nullptr;
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index e53c4ca..85acf94 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -432,6 +432,7 @@
   uint32_t active_refresh_rate_ = 0;
   bool disable_cwb_idle_fallback_ = false;
   bool allow_tonemap_native_ = false;
+  bool avoid_qsync_mode_change_ = false;
 
  private:
   // Max tolerable power-state-change wait-times in milliseconds.
@@ -481,6 +482,7 @@
   bool windowed_display_ = false;
   LayerRect window_rect_ = {};
   bool enable_win_rect_mask_ = false;
+  HWDisplayMode default_panel_mode_ = kModeDefault;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index 5402d8e..da704f5 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -389,7 +389,7 @@
 }
 
 void DisplayBuiltIn::UpdateQsyncMode() {
-  if (!hw_panel_info_.qsync_support) {
+  if (!hw_panel_info_.qsync_support || avoid_qsync_mode_change_) {
     return;
   }
 
@@ -921,11 +921,17 @@
   } else if (qsync_mode_ == kQsyncModeOneShotContinuous) {
     // No action needed.
   } else if (qsync_mode_ == kQSyncModeContinuous) {
-    needs_avr_update_ = false;
+      if (!avoid_qsync_mode_change_) {
+        needs_avr_update_ = false;
+      } else if (needs_avr_update_) {
+        validated_ = false;
+        event_handler_->Refresh();
+      }
   } else if (qsync_mode_ == kQSyncModeNone) {
     needs_avr_update_ = false;
   }
 
+  avoid_qsync_mode_change_ = false;
   SetVsyncStatus(true /*Re-enable vsync.*/);
 
   bool notify_idle = enable_qsync_idle_ && (active_qsync_mode_ != kQSyncModeNone) &&
@@ -1047,6 +1053,7 @@
       return error;
     }
 
+    avoid_qsync_mode_change_ = true;
     DisplayBase::ReconfigureDisplay();
 
     if (mode == kModeVideo) {
@@ -1999,6 +2006,7 @@
   }
 
   validated_ = false;
+  avoid_qsync_mode_change_ = true;
   DLOGV("Setting new dynamic bit clk value: %" PRIu64, bit_clk_rate);
   return hw_intf_->SetDynamicDSIClock(bit_clk_rate);
 }
diff --git a/sdm/libs/dal/hw_device_drm.cpp b/sdm/libs/dal/hw_device_drm.cpp
index 09b28ec..8164111 100644
--- a/sdm/libs/dal/hw_device_drm.cpp
+++ b/sdm/libs/dal/hw_device_drm.cpp
@@ -585,6 +585,14 @@
   PopulateHWPanelInfo();
   UpdateMixerAttributes();
 
+  LayerRect window_rect = {};
+  windowed_display_ = Debug::GetWindowRect(hw_panel_info_.is_primary_panel, &window_rect.left,
+                                           &window_rect.top, &window_rect.right,
+                                           &window_rect.bottom) == 0;
+  if (windowed_display_) {
+    window_rect_ = window_rect;
+  }
+
   // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor
   if (hw_resource_.has_qseed3) {
     hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
@@ -3059,6 +3067,13 @@
   sde_drm::DRMRect cwb_dst = full_frame;
   LayerRect cwb_roi = cwb_config->cwb_roi;
 
+  if (windowed_display_) {
+    cwb_roi.left += window_rect_.left;
+    cwb_roi.right += window_rect_.left;
+    cwb_roi.top += window_rect_.top;
+    cwb_roi.bottom += window_rect_.top;
+  }
+
   if (has_cwb_crop_) {  // If CWB ROI feature is supported, then set WB connector's roi_v1 property
     // to PU ROI and DST_* properties to CWB ROI. Else, set DST_* properties to full frame ROI.
     bool is_full_frame_update = IsFullFrameUpdate(hw_layer_info);
diff --git a/sdm/libs/dal/hw_device_drm.h b/sdm/libs/dal/hw_device_drm.h
index 144debf..63eba31 100644
--- a/sdm/libs/dal/hw_device_drm.h
+++ b/sdm/libs/dal/hw_device_drm.h
@@ -364,6 +364,8 @@
   static HWCwbConfig cwb_config_;
   static std::mutex cwb_state_lock_;  // cwb state lock. Set before accesing or updating cwb_config_
   uint32_t transfer_time_updated_ = 0;
+  LayerRect window_rect_ = {};
+  bool windowed_display_ = false;
 
  private:
   void GetCWBCapabilities();