Merge "sdm: Add support for scaler"
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index a0ac324..042db21 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -38,6 +38,8 @@
 extern "C" {
 #endif
 
+#define MAX_UBWC_STATS_LENGTH 32
+
 enum ColorSpace_t{
     ITU_R_601,
     ITU_R_601_FR,
@@ -63,6 +65,35 @@
     int32_t sliceHeight;
 };
 
+enum UBWC_Version {
+    UBWC_UNUSED      = 0,
+    UBWC_1_0         = 0x1,
+    UBWC_2_0         = 0x2,
+    UBWC_MAX_VERSION = 0xFF,
+};
+
+struct UBWC_2_0_Stats {
+    uint32_t nCRStatsTile32;  /**< UBWC Stats info for  32 Byte Tile */
+    uint32_t nCRStatsTile64;  /**< UBWC Stats info for  64 Byte Tile */
+    uint32_t nCRStatsTile96;  /**< UBWC Stats info for  96 Byte Tile */
+    uint32_t nCRStatsTile128; /**< UBWC Stats info for 128 Byte Tile */
+    uint32_t nCRStatsTile160; /**< UBWC Stats info for 160 Byte Tile */
+    uint32_t nCRStatsTile192; /**< UBWC Stats info for 192 Byte Tile */
+    uint32_t nCRStatsTile256; /**< UBWC Stats info for 256 Byte Tile */
+};
+
+struct UBWCStats {
+    enum UBWC_Version version; /* Union depends on this version. */
+    uint8_t bDataValid;      /* If [non-zero], CR Stats data is valid.
+                               * Consumers may use stats data.
+                               * If [zero], CR Stats data is invalid.
+                               * Consumers *Shall* not use stats data */
+    union {
+        struct UBWC_2_0_Stats ubwc_stats;
+        uint32_t reserved[MAX_UBWC_STATS_LENGTH]; /* This is for future */
+    };
+};
+
 struct S3DGpuComp_t {
     int32_t displayId; /* on which display S3D is composed by client */
     uint32_t s3dMode; /* the S3D format of this layer to be accessed by client */
@@ -99,6 +130,14 @@
     /* Color Aspects + HDR info */
     ColorMetaData color;
 #endif
+    /* Consumer should read this data as follows based on
+     * Gralloc flag "interlaced" listed above.
+     * [0] : If it is progressive.
+     * [0] : Top field, if it is interlaced.
+     * [1] : Do not read, if it is progressive.
+     * [1] : Bottom field, if it is interlaced.
+     */
+    struct UBWCStats ubwcCRStats[2];
 };
 
 enum DispParamType {
@@ -108,7 +147,7 @@
     UNUSED2                  = 0x0008,
     UNUSED3                  = 0x0010,
     UNUSED4                  = 0x0020,
-    UNUSED5                  = 0x0040,
+    SET_UBWC_CR_STATS_INFO   = 0x0040,
     UPDATE_BUFFER_GEOMETRY   = 0x0080,
     UPDATE_REFRESH_RATE      = 0x0100,
     UPDATE_COLOR_SPACE       = 0x0200,
@@ -124,6 +163,7 @@
     GET_VT_TIMESTAMP         = 0x0001,
     GET_COLOR_METADATA       = 0x0002,
     GET_PP_PARAM_INTERLACED  = 0x0004,
+    GET_UBWC_CR_STATS_INFO   = 0x0040,
     GET_BUFFER_GEOMETRY      = 0x0080,
     GET_REFRESH_RATE         = 0x0100,
     GET_COLOR_SPACE          = 0x0200,
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 3ccf454..030eaf1 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -234,12 +234,12 @@
   DisplayPort port = kPortDefault;    // Display port
   HWDisplayMode mode = kModeDefault;  // Display mode
   bool partial_update = false;        // Partial update feature
-  int left_align = 0;                 // ROI left alignment restriction
-  int width_align = 0;                // ROI width alignment restriction
-  int top_align = 0;                  // ROI top alignment restriction
-  int height_align = 0;               // ROI height alignment restriction
-  int min_roi_width = 0;              // Min width needed for ROI
-  int min_roi_height = 0;             // Min height needed for ROI
+  int left_align = 1;                 // ROI left alignment restriction
+  int width_align = 1;                // ROI width alignment restriction
+  int top_align = 1;                  // ROI top alignment restriction
+  int height_align = 1;               // ROI height alignment restriction
+  int min_roi_width = 1;              // Min width needed for ROI
+  int min_roi_height = 1;             // Min height needed for ROI
   bool needs_roi_merge = false;       // Merge ROI's of both the DSI's
   bool dynamic_fps = false;           // Panel Supports dynamic fps
   bool dfps_porch_mode = false;       // dynamic fps VFP or HFP mode
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index e6aa70f..8a5bd81 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -140,12 +140,18 @@
     return -EINVAL;
   }
 
+  SCOPE_LOCK(uevent_locker_);
+
   if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) {
     DLOGE("Failed to start = %s, error = %s", uevent_thread_name_, strerror(errno));
     CoreInterface::DestroyCore();
     return -errno;
   }
 
+  // Wait for uevent_init() to happen and let the uevent thread wait for uevents, so that hdmi
+  // connect/disconnect events won't be missed
+  uevent_locker_.Wait();
+
   // Read which display is first, and create it and store it in primary slot
   HWDisplayInterfaceInfo hw_disp_info;
   error = core_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
@@ -465,6 +471,8 @@
 }
 
 int HWCSession::EventControl(hwc_composer_device_1 *device, int disp, int event, int enable) {
+  SCOPE_LOCK(locker_);
+
   if (!device) {
     return -EINVAL;
   }
@@ -1418,14 +1426,21 @@
 void* HWCSession::HWCUeventThreadHandler() {
   static char uevent_data[PAGE_SIZE];
   int length = 0;
+
+  uevent_locker_.Lock();
   prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0);
   setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
   if (!uevent_init()) {
     DLOGE("Failed to init uevent");
     pthread_exit(0);
+    uevent_locker_.Signal();
+    uevent_locker_.Unlock();
     return NULL;
   }
 
+  uevent_locker_.Signal();
+  uevent_locker_.Unlock();
+
   while (!uevent_thread_exit_) {
     // keep last 2 zeroes to ensure double 0 termination
     length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index c3ffa98..1cd3e33 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -153,6 +153,7 @@
   bool is_hdmi_yuv_ = false;
   std::bitset<HWC_NUM_DISPLAY_TYPES> connected_displays_;  // Bit mask of connected displays
   HWCSocketHandler socket_handler_;
+  Locker uevent_locker_;
 };
 
 }  // namespace sdm