Merge "sdm: Fix Dynamic frame rate issue"
diff --git a/Android.mk b/Android.mk
index b5961ad..b8b893c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,14 +1,17 @@
-display-hals := libcopybit liblight libmemtrack libqservice libqdutils
+sdm-libs := sdm/libs
+display-hals := libqservice libqdutils $(sdm-libs)/utils $(sdm-libs)/core
+
+ifneq ($(TARGET_IS_HEADLESS), true)
+    display-hals += libcopybit liblight libmemtrack hdmi_cec \
+                    $(sdm-libs)/hwc $(sdm-libs)/hwc2
+endif
+
 ifneq ($(TARGET_USES_GRALLOC1), true)
     display-hals += libgralloc
 else
     display-hals += libgralloc1
 endif
 
-display-hals += hdmi_cec
-sdm-libs := sdm/libs
-display-hals += $(sdm-libs)/utils $(sdm-libs)/core $(sdm-libs)/hwc $(sdm-libs)/hwc2
-
 ifeq ($(call is-vendor-board-platform,QCOM),true)
     include $(call all-named-subdir-makefiles,$(display-hals))
 else
diff --git a/common.mk b/common.mk
index 6b3e2e9..e49c8c2 100644
--- a/common.mk
+++ b/common.mk
@@ -8,7 +8,10 @@
 
 common_includes := $(display_top)/libqdutils
 common_includes += $(display_top)/libqservice
-common_includes += $(display_top)/libcopybit
+ifneq ($(TARGET_IS_HEADLESS), true)
+    common_includes += $(display_top)/libcopybit
+endif
+
 common_includes += $(display_top)/sdm/include
 
 common_header_export_path := qcom/display
@@ -16,9 +19,15 @@
 #Common libraries external to display HAL
 common_libs := liblog libutils libcutils libhardware
 
+ifeq ($(TARGET_IS_HEADLESS), true)
+    LOCAL_CLANG := false
+else
+    LOCAL_CLANG := true
+endif
+
 #Common C flags
 common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers
-common_flags += -Wconversion -Wall -Werror
+common_flags += -Wconversion -Wall -Werror -std=c++11
 ifneq ($(TARGET_USES_GRALLOC1), true)
     common_flags += -isystem $(display_top)/libgralloc
 else
@@ -51,6 +60,10 @@
 #    common_flags += -DQTI_BSP
 # endif
 
+ifeq ($(TARGET_IS_HEADLESS),true)
+    common_flags += -DTARGET_HEADLESS
+endif
+
 ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
 # This check is to pick the kernel headers from the right location.
 # If the macro above is defined, we make the assumption that we have the kernel
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
index 03da814..5e499b3 100644
--- a/libgralloc/Android.mk
+++ b/libgralloc/Android.mk
@@ -21,10 +21,11 @@
 LOCAL_MODULE_RELATIVE_PATH    := hw
 LOCAL_MODULE_TAGS             := optional
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libmemalloc libqdMetaData
-LOCAL_SHARED_LIBRARIES        += libqdutils libGLESv1_CM
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libmemalloc libqdMetaData libqdutils
+ifneq ($(TARGET_IS_HEADLESS), true)
+LOCAL_SHARED_LIBRARIES        += libGLESv1_CM
+endif
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
-LOCAL_CLANG                   := true
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
 LOCAL_SRC_FILES               := gpu.cpp gralloc.cpp framebuffer.cpp mapper.cpp
 LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
@@ -40,7 +41,6 @@
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
 LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdutils libdl
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdmemalloc\" -Wno-sign-conversion
-LOCAL_CLANG                   := true
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
 LOCAL_SRC_FILES               := ionalloc.cpp alloc_controller.cpp
 LOCAL_COPY_HEADERS            := alloc_controller.h memalloc.h
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index e9cdc73..0ef0a9a 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -39,7 +39,7 @@
 #include <qdMetaData.h>
 #include <utils/Singleton.h>
 #include <utils/Mutex.h>
-
+#include <algorithm>
 
 #ifdef VENUS_COLOR_FORMAT
 #include <media/msm_media_info.h>
@@ -101,6 +101,7 @@
 MDPCapabilityInfo :: MDPCapabilityInfo() {
   qdutils::querySDEInfo(HAS_MACRO_TILE, &isMacroTileSupported);
   qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported);
+  qdutils::querySDEInfo(HAS_WB_UBWC, &isWBUBWCSupported);
 }
 
 //------------- AdrenoMemInfo-----------------------//
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index 5c297c1..dd4842f 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -34,7 +34,9 @@
 #include <linux/fb.h>
 #include <linux/msm_mdp.h>
 
+#ifndef TARGET_HEADLESS
 #include <GLES/gl.h>
+#endif
 
 #include "gralloc_priv.h"
 #include "fb_priv.h"
@@ -99,7 +101,9 @@
     if(!dev) {
         return -1;
     }
+#ifndef TARGET_HEADLESS
     glFinish();
+#endif
 
     return 0;
 }
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index c1d7788..c62cec0 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -267,9 +267,13 @@
        format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
         if (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC)
             grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
-        else if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
-            grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
-        else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)
+        else if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
+            if(MDPCapabilityInfo::getInstance().isWBUBWCSupportedByMDP() &&
+               usage & GRALLOC_USAGE_HW_COMPOSER)
+              grallocFormat = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+            else
+              grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
+        } else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)
                 == GRALLOC_USAGE_HW_CAMERA_ZSL)
             grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL; //NV21 ZSL
         else if(usage & GRALLOC_USAGE_HW_CAMERA_READ)
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 5fe1bdb..578240a 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -203,6 +203,7 @@
 {
     int isMacroTileSupported = 0;
     int isUBwcSupported = 0;
+    int isWBUBWCSupported = 0;
 
     public:
         MDPCapabilityInfo();
@@ -220,6 +221,13 @@
         *          0 : not supported
         */
         int isUBwcSupportedByMDP() { return isUBwcSupported; }
+        /*
+        * Function to return whether MDP WB block outputs UBWC format
+        *
+        * @return  1 : supported
+        *          0 : not supported
+        */
+        int isWBUBWCSupportedByMDP() { return isWBUBWCSupported; }
 };
 
 #endif /* GR_H_ */
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 142586b..24a0aa1 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -55,6 +55,27 @@
     return memalloc;
 }
 
+static int gralloc_map_metadata(buffer_handle_t handle) {
+    private_handle_t* hnd = (private_handle_t*)handle;
+    hnd->base_metadata = 0;
+    IMemAlloc* memalloc = getAllocator(hnd->flags) ;
+    void *mappedAddress = MAP_FAILED;
+    unsigned int size = 0;
+    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
+        mappedAddress = MAP_FAILED;
+        size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+        int ret = memalloc->map_buffer(&mappedAddress, size,
+                                       hnd->offset_metadata, hnd->fd_metadata);
+        if(ret || mappedAddress == MAP_FAILED) {
+            ALOGE("Could not mmap metadata for handle %p, fd=%d (%s)",
+                  hnd, hnd->fd_metadata, strerror(errno));
+            return -errno;
+        }
+        hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
+    }
+    return 0;
+}
+
 static int gralloc_map(gralloc_module_t const* module,
                        buffer_handle_t handle)
 {
@@ -68,7 +89,6 @@
     IMemAlloc* memalloc = getAllocator(hnd->flags) ;
     void *mappedAddress = MAP_FAILED;
     hnd->base = 0;
-    hnd->base_metadata = 0;
 
     // Dont map framebuffer and secure buffers
     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
@@ -83,23 +103,21 @@
         }
 
         hnd->base = uint64_t(mappedAddress) + hnd->offset;
+    } else {
+        // Cannot map secure buffers or framebuffers, but still need to map
+        // metadata for secure buffers.
+        // If mapping a secure buffers fails, the framework needs to get
+        // an error code.
+        err = -EINVAL;
     }
 
     //Allow mapping of metadata for all buffers including secure ones, but not
     //of framebuffer
-    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
-        mappedAddress = MAP_FAILED;
-        size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
-        err = memalloc->map_buffer(&mappedAddress, size,
-                                       hnd->offset_metadata, hnd->fd_metadata);
-        if(err || mappedAddress == MAP_FAILED) {
-            ALOGE("Could not mmap handle %p, fd=%d (%s)",
-                  handle, hnd->fd_metadata, strerror(errno));
-            return -errno;
-        }
-        hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
+    int metadata_err = gralloc_map_metadata(handle);
+    if (!err) {
+        err = metadata_err;
     }
-    return 0;
+    return err;
 }
 
 static int gralloc_unmap(gralloc_module_t const* module,
@@ -152,21 +170,11 @@
     ATRACE_CALL();
     if (!module || private_handle_t::validate(handle) < 0)
         return -EINVAL;
-
-    /* NOTE: we need to initialize the buffer as not mapped/not locked
-     * because it shouldn't when this function is called the first time
-     * in a new process. Ideally these flags shouldn't be part of the
-     * handle, but instead maintained in the kernel or at least
-     * out-of-line
-     */
-
-    int err = gralloc_map(module, handle);
-    if (err) {
-        ALOGE("%s: gralloc_map failed", __FUNCTION__);
-        return err;
-    }
-
-    return 0;
+    // The base address received via IPC is invalid in this process
+    // Reset it to 0 here since it will be mapped in lock()
+    private_handle_t* hnd = (private_handle_t*)handle;
+    hnd->base = 0;
+    return gralloc_map_metadata(handle);
 }
 
 int gralloc_unregister_buffer(gralloc_module_t const* module,
diff --git a/liblight/Android.mk b/liblight/Android.mk
index 8aff542..ff4825b 100644
--- a/liblight/Android.mk
+++ b/liblight/Android.mk
@@ -20,7 +20,7 @@
 LOCAL_SRC_FILES := lights.c
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdlights\"
+LOCAL_CFLAGS := -DLOG_TAG=\"qdlights\"
 LOCAL_CLANG  := true
 LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM)
 LOCAL_MODULE_TAGS := optional
diff --git a/libqdutils/Android.mk b/libqdutils/Android.mk
index f56f774..db6509c 100644
--- a/libqdutils/Android.mk
+++ b/libqdutils/Android.mk
@@ -4,10 +4,9 @@
 
 LOCAL_MODULE                  := libqdutils
 LOCAL_MODULE_TAGS             := optional
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libui libbinder libqservice
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libbinder libqservice
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdutils\" -Wno-sign-conversion
-LOCAL_CLANG                   := true
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
 LOCAL_COPY_HEADERS            := display_config.h
@@ -26,7 +25,7 @@
 LOCAL_SRC_FILES                 := qdMetaData.cpp
 LOCAL_CFLAGS                    := $(common_flags) -Wno-sign-conversion
 LOCAL_CFLAGS                    += -DLOG_TAG=\"DisplayMetaData\"
-LOCAL_CLANG                     := true
+
 LOCAL_MODULE_TAGS               := optional
 LOCAL_MODULE                    := libqdMetaData
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libqdutils/qd_utils.cpp b/libqdutils/qd_utils.cpp
index 6453b58..43fb715 100644
--- a/libqdutils/qd_utils.cpp
+++ b/libqdutils/qd_utils.cpp
@@ -61,11 +61,12 @@
     case HAS_MACRO_TILE:
         featureName = "tile_format";
         break;
-
     case HAS_UBWC:
         featureName = "ubwc";
         break;
-
+    case HAS_WB_UBWC:
+        featureName = "wb_ubwc";
+        break;
     default:
         ALOGE("Invalid query type %d", type);
         return -EINVAL;
diff --git a/libqdutils/qd_utils.h b/libqdutils/qd_utils.h
index 0392e05..4722dcd 100644
--- a/libqdutils/qd_utils.h
+++ b/libqdutils/qd_utils.h
@@ -49,6 +49,7 @@
 enum HWQueryType {
     HAS_MACRO_TILE = 0,
     HAS_UBWC = 1,
+    HAS_WB_UBWC = 2
 };
 
 enum {
diff --git a/libqservice/Android.mk b/libqservice/Android.mk
index 285afca..5c1eaba 100644
--- a/libqservice/Android.mk
+++ b/libqservice/Android.mk
@@ -7,7 +7,6 @@
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
 LOCAL_SHARED_LIBRARIES        := $(common_libs) libbinder
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdqservice\" -Wno-sign-conversion
-LOCAL_CLANG                   := true
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_SRC_FILES               := QService.cpp \
                                  IQService.cpp \
diff --git a/sdm/include/utils/sys.h b/sdm/include/utils/sys.h
index c06b7f8..b90007a 100644
--- a/sdm/include/utils/sys.h
+++ b/sdm/include/utils/sys.h
@@ -49,7 +49,11 @@
 #endif
 
   // Pointers to system calls which are either mapped to actual system call or virtual driver.
+#ifdef TARGET_HEADLESS
+  typedef int (*ioctl)(int, unsigned long int, ...);  // NOLINT
+#else
   typedef int (*ioctl)(int, int, ...);
+#endif
   typedef int (*open)(const char *, int, ...);
   typedef int (*close)(int);
   typedef int (*poll)(struct pollfd *, nfds_t, int);
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index 5e88683..08d81b4 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -5,12 +5,9 @@
 LOCAL_MODULE                  := libsdmcore
 LOCAL_MODULE_TAGS             := optional
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_CFLAGS                  := -Wno-missing-field-initializers -Wno-unused-parameter \
-                                 -std=c++11 -fcolor-diagnostics\
-                                 -DLOG_TAG=\"SDM\" $(common_flags)
-LOCAL_CLANG                   := true
+LOCAL_CFLAGS                  := -Wno-unused-parameter -DLOG_TAG=\"SDM\" $(common_flags)
 LOCAL_HW_INTF_PATH            := fb
-LOCAL_SHARED_LIBRARIES        := libdl libsdmutils libc++
+LOCAL_SHARED_LIBRARIES        := libdl libsdmutils
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
 LOCAL_SRC_FILES               := core_interface.cpp \
                                  core_impl.cpp \
diff --git a/sdm/libs/core/fb/hw_events.cpp b/sdm/libs/core/fb/hw_events.cpp
index 5ae53a4..4015796 100644
--- a/sdm/libs/core/fb/hw_events.cpp
+++ b/sdm/libs/core/fb/hw_events.cpp
@@ -80,7 +80,7 @@
 pollfd HWEvents::InitializePollFd(HWEventData *event_data) {
   char node_path[kMaxStringLength] = {0};
   char data[kMaxStringLength] = {0};
-  pollfd poll_fd;
+  pollfd poll_fd = {0};
   poll_fd.fd = -1;
 
   if (!strncmp(event_data->event_name, "thread_exit", strlen("thread_exit"))) {
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index 43eaaba..b00968c 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -1380,6 +1380,7 @@
 int HWCSession::HotPlugHandler(bool connected) {
   int status = 0;
   bool notify_hotplug = false;
+  bool refresh_screen = false;
 
   // To prevent sending events to client while a lock is held, acquire scope locks only within
   // below scope so that those get automatically unlocked after the scope ends.
@@ -1423,6 +1424,11 @@
           return -1;
         }
 
+        status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetPowerMode(HWC_POWER_MODE_NORMAL);
+        if (status) {
+          DLOGE("power-on on primary failed with error = %d", status);
+        }
+
         is_hdmi_yuv_ = IsDisplayYUV(HWC_DISPLAY_PRIMARY);
 
         // Next, go ahead and enable vsync on external display. This is expliclity required
@@ -1435,6 +1441,7 @@
         }
         // Don't do hotplug notification for HDMI as primary case for now
         notify_hotplug = false;
+        refresh_screen = true;
       } else {
         if (hwc_display_[HWC_DISPLAY_EXTERNAL]) {
           DLOGE("HDMI is already connected");
@@ -1493,7 +1500,7 @@
     }
   }
 
-  if (connected && notify_hotplug) {
+  if (connected && (notify_hotplug || refresh_screen)) {
     // trigger screen refresh to ensure sufficient resources are available to process new
     // new display connection.
     hwc_procs_->invalidate(hwc_procs_);
diff --git a/sdm/libs/utils/Android.mk b/sdm/libs/utils/Android.mk
index f482a6d..928f3c4 100644
--- a/sdm/libs/utils/Android.mk
+++ b/sdm/libs/utils/Android.mk
@@ -5,10 +5,7 @@
 LOCAL_MODULE                  := libsdmutils
 LOCAL_MODULE_TAGS             := optional
 LOCAL_C_INCLUDES              := $(common_includes)
-LOCAL_CFLAGS                  := -Wno-missing-field-initializers \
-                                 -std=c++11 -fcolor-diagnostics\
-                                 -DLOG_TAG=\"SDM\" $(common_flags)
-LOCAL_CLANG                   := true
+LOCAL_CFLAGS                  := -DLOG_TAG=\"SDM\" $(common_flags)
 LOCAL_SRC_FILES               := debug.cpp \
                                  rect.cpp \
                                  sys.cpp \