Merge "config: set the late App phase-offset for high fps for all products"
diff --git a/composer/Android.mk b/composer/Android.mk
index 765a3e4..306a7dc 100644
--- a/composer/Android.mk
+++ b/composer/Android.mk
@@ -45,7 +45,8 @@
                                  vendor.display.config@1.10 \
                                  vendor.display.config@1.11 \
                                  vendor.display.config@1.12 \
-                                 vendor.display.config@1.13
+                                 vendor.display.config@1.13 \
+                                 vendor.display.config@1.14
 
 LOCAL_SRC_FILES               := QtiComposer.cpp QtiComposerClient.cpp service.cpp \
                                  QtiComposerHandleImporter.cpp \
diff --git a/composer/hwc_display_builtin.cpp b/composer/hwc_display_builtin.cpp
index b7b6515..439170a 100644
--- a/composer/hwc_display_builtin.cpp
+++ b/composer/hwc_display_builtin.cpp
@@ -1103,6 +1103,7 @@
   if (!is_primary_) {
     // Disable on all non-primary builtins.
     DLOGI("Non-primary builtin.");
+    disable_layer_stitch_ = true;
     return true;
   }
 
diff --git a/composer/hwc_display_dummy.cpp b/composer/hwc_display_dummy.cpp
index eff0ed6..315a22c 100644
--- a/composer/hwc_display_dummy.cpp
+++ b/composer/hwc_display_dummy.cpp
@@ -59,6 +59,10 @@
   return HWC2::Error::None;
 }
 
+HWC2::Error HWCDisplayDummy::SetColorMode(ColorMode mode) {
+  return HWC2::Error::None;
+}
+
 HWCDisplayDummy::HWCDisplayDummy(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
                                  HWCCallbacks *callbacks, HWCDisplayEventHandler *event_handler,
                                  qService::QService *qservice, hwc2_display_t id,
diff --git a/composer/hwc_display_dummy.h b/composer/hwc_display_dummy.h
index bf28a03..8f78303 100644
--- a/composer/hwc_display_dummy.h
+++ b/composer/hwc_display_dummy.h
@@ -46,6 +46,7 @@
   virtual HWC2::Error Present(int32_t *out_retire_fence);
   virtual HWC2::Error GetActiveConfig(hwc2_config_t *out_config);
   virtual HWC2::Error UpdatePowerMode(HWC2::PowerMode mode);
+  virtual HWC2::Error SetColorMode(ColorMode mode);
 
  private:
   HWCDisplayDummy(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
diff --git a/composer/hwc_layers.cpp b/composer/hwc_layers.cpp
index eb0687e..ee8207b 100644
--- a/composer/hwc_layers.cpp
+++ b/composer/hwc_layers.cpp
@@ -234,7 +234,7 @@
   if (!buffer) {
     if (client_requested_ == HWC2::Composition::Device ||
         client_requested_ == HWC2::Composition::Cursor) {
-      DLOGE("Invalid buffer handle: %p on layer: %d client requested comp type %d", buffer, id_,
+      DLOGW("Invalid buffer handle: %p on layer: %d client requested comp type %d", buffer, id_,
             client_requested_);
       ::close(acquire_fence);
       return HWC2::Error::BadParameter;
diff --git a/composer/hwc_session.h b/composer/hwc_session.h
index 8e2e25c..aabf77a 100644
--- a/composer/hwc_session.h
+++ b/composer/hwc_session.h
@@ -20,7 +20,7 @@
 #ifndef __HWC_SESSION_H__
 #define __HWC_SESSION_H__
 
-#include <vendor/display/config/1.13/IDisplayConfig.h>
+#include <vendor/display/config/1.14/IDisplayConfig.h>
 #include <vendor/qti/hardware/display/composer/2.0/IQtiComposerClient.h>
 
 #include <core/core_interface.h>
@@ -49,7 +49,7 @@
 
 namespace sdm {
 
-using vendor::display::config::V1_13::IDisplayConfig;
+using vendor::display::config::V1_14::IDisplayConfig;
 using vendor::display::config::V1_10::IDisplayCWBCallback;
 
 using ::android::hardware::Return;
@@ -410,6 +410,7 @@
                                      const hidl_handle& buffer) override;
   Return<int32_t> setQsyncMode(uint32_t disp_id, IDisplayConfig::QsyncMode mode) override;
   Return<bool> isSmartPanelConfig(uint32_t disp_id, uint32_t config_id) override;
+  Return<bool> isRotatorSupportedFormat(int hal_format, bool ubwc) override;
 
   // QClient methods
   virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
diff --git a/composer/hwc_session_services.cpp b/composer/hwc_session_services.cpp
index 1881c26..a9c340a 100644
--- a/composer/hwc_session_services.cpp
+++ b/composer/hwc_session_services.cpp
@@ -1048,6 +1048,7 @@
 
       if (release_fence >= 0) {
         status = sync_wait(release_fence, 1000);
+        close(release_fence);
       } else {
         DLOGE("CWB release fence could not be retrieved.");
         status = -1;
@@ -1147,4 +1148,16 @@
   return INT32(status);
 }
 
+Return<bool> HWCSession::isRotatorSupportedFormat(int hal_format, bool ubwc) {
+  if (!core_intf_) {
+    DLOGW("core_intf_ not initialized.");
+    return false;
+  }
+  int flag = ubwc ? private_handle_t::PRIV_FLAGS_UBWC_ALIGNED : 0;
+
+  LayerBufferFormat sdm_format = HWCLayer::GetSDMFormat(hal_format, flag);
+
+  return core_intf_->IsRotatorSupportedFormat(sdm_format);
+}
+
 }  // namespace sdm
diff --git a/composer/vendor.qti.hardware.display.composer-service.xml b/composer/vendor.qti.hardware.display.composer-service.xml
index 5184413..0d4ef00 100644
--- a/composer/vendor.qti.hardware.display.composer-service.xml
+++ b/composer/vendor.qti.hardware.display.composer-service.xml
@@ -48,7 +48,7 @@
     <hal format="hidl">
         <name>vendor.display.config</name>
         <transport>hwbinder</transport>
-        <version>1.13</version>
+        <version>1.14</version>
         <interface>
             <name>IDisplayConfig</name>
             <instance>default</instance>
diff --git a/config/display-product.mk b/config/display-product.mk
index 792e4dc..6d661ca 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -29,6 +29,7 @@
     vendor.display.config@1.11.vendor \
     vendor.display.config@1.12.vendor \
     vendor.display.config@1.13.vendor \
+    vendor.display.config@1.14.vendor \
     vendor.qti.hardware.display.mapper@2.0.vendor \
     vendor.qti.hardware.display.mapper@3.0.vendor \
     modetest
diff --git a/sdm/include/core/core_interface.h b/sdm/include/core/core_interface.h
index 90b496d..072b677 100644
--- a/sdm/include/core/core_interface.h
+++ b/sdm/include/core/core_interface.h
@@ -258,6 +258,14 @@
   */
   virtual DisplayError GetMaxDisplaysSupported(DisplayType type, int32_t *max_displays) = 0;
 
+  /*! @brief Method which returns true if the given format is supported by rotator otherwise false
+
+    @param[in] \link LayerBufferFormat \endlink
+
+    @return returns true if the given format is supported by rotator otherwise false
+  */
+  virtual bool IsRotatorSupportedFormat(LayerBufferFormat format) = 0;
+
  protected:
   virtual ~CoreInterface() { }
 };
diff --git a/sdm/include/private/resource_interface.h b/sdm/include/private/resource_interface.h
index 56db4ce..4baef57 100644
--- a/sdm/include/private/resource_interface.h
+++ b/sdm/include/private/resource_interface.h
@@ -73,6 +73,7 @@
   virtual DisplayError SetDetailEnhancerData(Handle display_ctx,
                                              const DisplayDetailEnhancerData &de_data) = 0;
   virtual DisplayError Perform(int cmd, ...) = 0;
+  virtual bool IsRotatorSupportedFormat(LayerBufferFormat format) = 0;
   virtual ~ResourceInterface() { }
 };
 
diff --git a/sdm/include/utils/fence.h b/sdm/include/utils/fence.h
new file mode 100644
index 0000000..94bb01b
--- /dev/null
+++ b/sdm/include/utils/fence.h
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2019, 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:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __FENCE_H__
+#define __FENCE_H__
+
+#include <core/buffer_sync_handler.h>
+#include <unistd.h>
+#include <utility>
+#include <memory>
+#include <string>
+
+namespace sdm {
+
+using std::shared_ptr;
+using std::string;
+
+class Fence {
+ public:
+  ~Fence();
+
+  static void Set(BufferSyncHandler *buffer_sync_handler);
+
+  // Ownership of the file descriptor is transferred to this method.
+  // Client must not close the file descriptor anymore regardless of the object creation status.
+  // nullptr will be retured for invalid fd i.e. -1.
+  static shared_ptr<Fence> Create(int fd);
+
+  // Ownership of returned fd lies with caller. Caller must explicitly close the fd.
+  static int Dup(const shared_ptr<Fence> &fence);
+
+  static shared_ptr<Fence> Merge(const shared_ptr<Fence> &fence1, const shared_ptr<Fence> &fence2);
+  static DisplayError Wait(const shared_ptr<Fence> &fence);
+  static DisplayError Wait(const shared_ptr<Fence> &fence, int timeout);
+  static string GetStr(const shared_ptr<Fence> &fence);
+
+ private:
+  explicit Fence(int fd);
+  Fence(const Fence &fence) = delete;
+  Fence& operator=(const Fence &fence) = delete;
+  Fence(Fence &&fence) = delete;
+  Fence& operator=(Fence &&fence) = delete;
+  static int Get(const shared_ptr<Fence> &fence);
+
+  static BufferSyncHandler *buffer_sync_handler_;
+  int fd_ = -1;
+};
+
+}  // namespace sdm
+
+#endif  // __FENCE_H__
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index 1bd6862..2500bd5 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -411,6 +411,12 @@
   DisplayCompositionContext *display_comp_ctx =
                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
 
+  Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
+  error = resource_intf_->Stop(display_resource_ctx, hw_layers);
+  if (error != kErrorNone) {
+    DLOGE("Resource stop failed for display = %d", display_comp_ctx->display_type);
+  }
+
   error = resource_intf_->PostCommit(display_comp_ctx->display_resource_ctx, hw_layers);
   if (error != kErrorNone) {
     return error;
@@ -419,14 +425,11 @@
   display_comp_ctx->idle_fallback = false;
   display_comp_ctx->first_cycle_ = false;
 
-  Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
-  error = resource_intf_->Stop(display_resource_ctx, hw_layers);
-
   DLOGV_IF(kTagCompManager, "Registered displays [%s], display %d-%d",
            StringDisplayList(registered_displays_), display_comp_ctx->display_id,
            display_comp_ctx->display_type);
 
-  return error;
+  return kErrorNone;
 }
 
 void CompManager::Purge(Handle display_ctx) {
@@ -687,4 +690,12 @@
   return res_wait_needed;
 }
 
+bool CompManager::IsRotatorSupportedFormat(LayerBufferFormat format) {
+  if (resource_intf_) {
+    return resource_intf_->IsRotatorSupportedFormat(format);
+  }
+
+  return false;
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index 15b6437..6846eda 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -89,6 +89,7 @@
   DisplayError CheckEnforceSplit(Handle comp_handle, uint32_t new_refresh_rate);
   DppsControlInterface* GetDppsControlIntf() { return dpps_ctrl_intf_; }
   bool CheckResourceState(Handle display_ctx);
+  bool IsRotatorSupportedFormat(LayerBufferFormat format);
 
  private:
   static const int kMaxThermalLevel = 3;
diff --git a/sdm/libs/core/core_impl.cpp b/sdm/libs/core/core_impl.cpp
index 8aaac7c..9b0eaec 100644
--- a/sdm/libs/core/core_impl.cpp
+++ b/sdm/libs/core/core_impl.cpp
@@ -254,5 +254,10 @@
   return hw_info_intf_->GetMaxDisplaysSupported(type, max_displays);
 }
 
+bool CoreImpl::IsRotatorSupportedFormat(LayerBufferFormat format) {
+  SCOPE_LOCK(locker_);
+  return comp_mgr_.IsRotatorSupportedFormat(format);
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/core_impl.h b/sdm/libs/core/core_impl.h
index 94e61d7..4af2311 100644
--- a/sdm/libs/core/core_impl.h
+++ b/sdm/libs/core/core_impl.h
@@ -62,6 +62,7 @@
   virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info);
   virtual DisplayError GetDisplaysStatus(HWDisplaysInfo *hw_displays_info);
   virtual DisplayError GetMaxDisplaysSupported(DisplayType type, int32_t *max_displays);
+  virtual bool IsRotatorSupportedFormat(LayerBufferFormat format);
 
  protected:
   Locker locker_;
diff --git a/sdm/libs/core/fb/hw_info.cpp b/sdm/libs/core/fb/hw_info.cpp
index b076aad..fef95fd 100644
--- a/sdm/libs/core/fb/hw_info.cpp
+++ b/sdm/libs/core/fb/hw_info.cpp
@@ -126,7 +126,7 @@
               if (!strncmp(tokens[j], "fmts_supported", strlen("fmts_supported"))) {
                 char *tokens_fmt[max_count] = { NULL };
                 // uint32_t token_fmt_count = 0;
-                if (tokens_fmt == NULL) {}
+                if (&tokens_fmt[0] == NULL) {}
               }
             }
             hw_resource_->hw_pipes.push_back(pipe_caps);
diff --git a/sdm/libs/core/resource_default.h b/sdm/libs/core/resource_default.h
index d51008b..6a2c90c 100644
--- a/sdm/libs/core/resource_default.h
+++ b/sdm/libs/core/resource_default.h
@@ -67,6 +67,7 @@
                                              const DisplayDetailEnhancerData &de_data);
   virtual DisplayError Perform(int cmd, ...) { return kErrorNone; }
   DisplayError SetDisplayState(int32_t display_id, DisplayState state) { return kErrorNone; }
+  virtual bool IsRotatorSupportedFormat(LayerBufferFormat format) { return false; }
 
  private:
   enum PipeOwner {
diff --git a/sdm/libs/utils/Android.mk b/sdm/libs/utils/Android.mk
index f4b09c6..c474193 100644
--- a/sdm/libs/utils/Android.mk
+++ b/sdm/libs/utils/Android.mk
@@ -12,6 +12,7 @@
 LOCAL_SRC_FILES               := debug.cpp \
                                  rect.cpp \
                                  sys.cpp \
+                                 fence.cpp \
                                  formats.cpp \
                                  utils.cpp
 
@@ -30,6 +31,7 @@
                                  $(SDM_HEADER_PATH)/utils/sys.h \
                                  $(SDM_HEADER_PATH)/utils/sync_task.h \
                                  $(SDM_HEADER_PATH)/utils/utils.h \
+                                 $(SDM_HEADER_PATH)/utils/fence.h \
                                  $(SDM_HEADER_PATH)/utils/factory.h
 
 include $(BUILD_COPY_HEADERS)
diff --git a/sdm/libs/utils/fence.cpp b/sdm/libs/utils/fence.cpp
new file mode 100644
index 0000000..3cf26e4
--- /dev/null
+++ b/sdm/libs/utils/fence.cpp
@@ -0,0 +1,110 @@
+/*
+* Copyright (c) 2019, 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:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <utils/fence.h>
+#include <string>
+
+#define __CLASS__ "Fence"
+
+namespace sdm {
+
+BufferSyncHandler* Fence::buffer_sync_handler_ = nullptr;
+
+Fence::Fence(int fd) : fd_(fd) {
+}
+
+Fence::~Fence() {
+  close(fd_);
+}
+
+void Fence::Set(BufferSyncHandler *buffer_sync_handler) {
+  buffer_sync_handler_ = buffer_sync_handler;
+}
+
+shared_ptr<Fence> Fence::Create(int fd) {
+  // Do not create Fence object for invalid fd, so that nullptr can be used for invalid fences.
+  if (fd < 0) {
+    return nullptr;
+  }
+
+  shared_ptr<Fence> fence(new Fence(fd));
+  if (!fence) {
+    close(fd);
+  }
+
+  return fence;
+}
+
+int Fence::Dup(const shared_ptr<Fence> &fence) {
+  if (!fence) {
+    return -1;
+  }
+
+  return dup(fence->fd_);
+}
+
+shared_ptr<Fence> Fence::Merge(const shared_ptr<Fence> &fence1, const shared_ptr<Fence> &fence2) {
+  if (!buffer_sync_handler_) {
+    return nullptr;
+  }
+
+  int fd1 = fence1 ? fence1->fd_ : -1;
+  int fd2 = fence2 ? fence2->fd_ : -1;
+  int merged = -1;
+
+  buffer_sync_handler_->SyncMerge(fd1, fd2, &merged);
+
+  return Create(merged);
+}
+
+DisplayError Fence::Wait(const shared_ptr<Fence> &fence) {
+  if (!buffer_sync_handler_) {
+    return kErrorUndefined;
+  }
+
+  return buffer_sync_handler_->SyncWait(Fence::Get(fence));
+}
+
+DisplayError Fence::Wait(const shared_ptr<Fence> &fence, int timeout) {
+  if (!buffer_sync_handler_) {
+    return kErrorUndefined;
+  }
+
+  return buffer_sync_handler_->SyncWait(Fence::Get(fence), timeout);
+}
+
+string Fence::GetStr(const shared_ptr<Fence> &fence) {
+  return std::to_string(Fence::Get(fence));
+}
+
+int Fence::Get(const shared_ptr<Fence> &fence) {
+  return (fence ? fence->fd_ : -1);
+}
+
+}  // namespace sdm