Merge "hwc: Map dirtyRect to layer destination before using."
diff --git a/libcopybit/Android.mk b/libcopybit/Android.mk
index b3d4249..2ac7d15 100644
--- a/libcopybit/Android.mk
+++ b/libcopybit/Android.mk
@@ -17,7 +17,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_COPY_HEADERS_TO         := $(common_header_export_path)
-LOCAL_COPY_HEADERS            := copybit.h copybit_priv.h
+LOCAL_COPY_HEADERS            := copybit.h copybit_priv.h c2d2.h
 #Copy the headers regardless of whether copybit is built
 include $(BUILD_COPY_HEADERS)
 
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index 852b8c0..771d483 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -35,8 +35,6 @@
 
 #include <EGL/eglplatform.h>
 #include <cutils/native_handle.h>
-#include <cutils/ashmem.h>
-#include <linux/ashmem.h>
 #include <gralloc_priv.h>
 
 #include <copybit.h>
@@ -259,6 +257,7 @@
 static int get_format(int format) {
     switch (format) {
         case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
+        case HAL_PIXEL_FORMAT_RGB_888:        return C2D_COLOR_FORMAT_888_RGB;
         case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
                                               C2D_FORMAT_SWAP_RB |
                                                   C2D_FORMAT_DISABLE_ALPHA;
@@ -317,6 +316,9 @@
         case C2D_COLOR_FORMAT_8888_ARGB:
             c2dBpp = 32;
             break;
+        case C2D_COLOR_FORMAT_888_RGB:
+            c2dBpp = 24;
+            break;
         case C2D_COLOR_FORMAT_8_L:
         case C2D_COLOR_FORMAT_8_A:
             c2dBpp = 8;
@@ -398,6 +400,7 @@
     switch(format) {
         case HAL_PIXEL_FORMAT_RGBA_8888:
         case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_RGB_888:
         case HAL_PIXEL_FORMAT_RGB_565:
         case HAL_PIXEL_FORMAT_BGRA_8888: {
             return COPYBIT_SUCCESS;
diff --git a/libgralloc/gpu.h b/libgralloc/gpu.h
index a34ff7e..5837588 100644
--- a/libgralloc/gpu.h
+++ b/libgralloc/gpu.h
@@ -24,7 +24,6 @@
 #include <string.h>
 
 #include <cutils/log.h>
-#include <cutils/ashmem.h>
 
 #include "gralloc_priv.h"
 #include "fb_priv.h"
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 338f9db..189d205 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -26,11 +26,9 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
-#include <linux/ashmem.h>
 
 #include <cutils/log.h>
 #include <cutils/atomic.h>
-#include <cutils/ashmem.h>
 
 #include <hardware/hardware.h>
 #include <hardware/gralloc.h>
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 237cd39..1539f3b 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -548,7 +548,8 @@
         if(ctx->mMDP.hasOverlay) {
             supported |= HWC_DISPLAY_VIRTUAL_BIT;
             if(!(qdutils::MDPVersion::getInstance().is8x26() ||
-                        qdutils::MDPVersion::getInstance().is8x16()))
+                        qdutils::MDPVersion::getInstance().is8x16() ||
+                        qdutils::MDPVersion::getInstance().is8x39()))
                 supported |= HWC_DISPLAY_EXTERNAL_BIT;
         }
         value[0] = supported;
diff --git a/libhwcomposer/hwc_ad.cpp b/libhwcomposer/hwc_ad.cpp
index fdf6e67..49e7e2a 100644
--- a/libhwcomposer/hwc_ad.cpp
+++ b/libhwcomposer/hwc_ad.cpp
@@ -41,37 +41,6 @@
 using namespace overlay::utils;
 namespace qhwc {
 
-//Opens writeback framebuffer and returns fd.
-static int openWbFb() {
-    int wbFd = -1;
-    //Check opening which FB would connect LM to WB
-    const int wbFbNum = Overlay::getFbForDpy(Overlay::DPY_WRITEBACK);
-    if(wbFbNum >= 0) {
-        char wbFbPath[256];
-        snprintf (wbFbPath, sizeof(wbFbPath),
-                "/sys/class/graphics/fb%d", wbFbNum);
-        //Opening writeback fb first time would create ad node if the device
-        //supports adaptive display
-        wbFd = open(wbFbPath, O_RDONLY);
-        if(wbFd < 0) {
-            ALOGE("%s: Failed to open /sys/class/graphics/fb%d with error %s",
-                    __func__, wbFbNum, strerror(errno));
-        }
-    } else {
-        ALOGD_IF(DEBUG, "%s: No writeback available", __func__);
-    }
-    return wbFd;
-}
-
-static inline void closeWbFb(int& fd) {
-    if(fd >= 0) {
-        close(fd);
-        fd = -1;
-    } else {
-        ALOGE("%s: Invalid fd %d", __func__, fd);
-    }
-}
-
 //Helper to write data to ad node
 static void adWrite(const int& value) {
     const int wbFbNum = Overlay::getFbForDpy(Overlay::DPY_WRITEBACK);
@@ -124,32 +93,31 @@
     return ret;
 }
 
-AssertiveDisplay::AssertiveDisplay(hwc_context_t *ctx) : mWbFd(-1),
-        mDoable(false), mFeatureEnabled(false),
-        mDest(overlay::utils::OV_INVALID) {
-    int fd = openWbFb();
-    if(fd >= 0) {
-        //Values in ad node:
-        //-1 means feature is disabled on device
-        // 0 means feature exists but turned off, will be turned on by hwc
-        // 1 means feature is turned on by hwc
-        // Plus, we do this feature only on split primary displays.
-        // Plus, we do this feature only if ro.qcom.ad=2
+AssertiveDisplay::AssertiveDisplay(hwc_context_t *ctx) :
+     mTurnedOff(true), mFeatureEnabled(false),
+     mDest(overlay::utils::OV_INVALID)
+{
+    //Values in ad node:
+    //-1 means feature is disabled on device
+    // 0 means feature exists but turned off, will be turned on by hwc
+    // 1 means feature is turned on by hwc
+    // Plus, we do this feature only on split primary displays.
+    // Plus, we do this feature only if ro.qcom.ad=2
 
-        char property[PROPERTY_VALUE_MAX];
-        const int ENABLED = 2;
-        int val = 0;
+    char property[PROPERTY_VALUE_MAX];
+    const int ENABLED = 2;
+    int val = 0;
 
-        if(property_get("ro.qcom.ad", property, "0") > 0) {
-            val = atoi(property);
-        }
+    if(property_get("ro.qcom.ad", property, "0") > 0) {
+        val = atoi(property);
+    }
 
-        if(adRead() >= 0 && isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY) &&
-                val == ENABLED) {
-            ALOGD_IF(DEBUG, "Assertive display feature supported");
-            mFeatureEnabled = true;
-        }
-        closeWbFb(fd);
+    if(adRead() >= 0 && isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY) &&
+            val == ENABLED) {
+        ALOGD_IF(DEBUG, "Assertive display feature supported");
+        mFeatureEnabled = true;
+        // If feature exists but is turned off, set mTurnedOff to true
+        mTurnedOff = adRead() > 0 ? false : true;
     }
 }
 
@@ -168,17 +136,24 @@
     }
 }
 
+void AssertiveDisplay::turnOffAD() {
+    if(mFeatureEnabled) {
+        if(!mTurnedOff) {
+            const int off = 0;
+            adWrite(off);
+            mTurnedOff = true;
+        }
+    }
+    mDoable = false;
+}
+
 bool AssertiveDisplay::prepare(hwc_context_t *ctx,
         const hwc_rect_t& crop,
         const Whf& whf,
         const private_handle_t *hnd) {
     if(!isDoable()) {
-        if(isModeOn()) {
-            //Cleanup one time during this switch
-            const int off = 0;
-            adWrite(off);
-            closeWbFb(mWbFd);
-        }
+        //Cleanup one time during this switch
+        turnOffAD();
         return false;
     }
 
@@ -246,27 +221,30 @@
     }
 
     mDest = dest;
-    if(!isModeOn()) {
-        mWbFd = openWbFb();
-        if(mWbFd >= 0) {
-            //write to sysfs, one time during this switch
-            const int on = 1;
-            adWrite(on);
-        }
-    }
-
-    if(!ctx->mOverlay->validateAndSet(overlay::Overlay::DPY_WRITEBACK,
-            mWbFd)) {
+    int wbFd = wb->getFbFd();
+    if(mFeatureEnabled && wbFd >= 0 &&
+        !ctx->mOverlay->validateAndSet(overlay::Overlay::DPY_WRITEBACK, wbFd))
+    {
         ALOGE("%s: Failed to validate and set overlay for dpy %d"
                 ,__FUNCTION__, overlay::Overlay::DPY_WRITEBACK);
+        turnOffAD();
         return false;
     }
 
+    // Only turn on AD if there are no errors during configuration stage
+    // and if it was previously in OFF state.
+    if(mFeatureEnabled && mTurnedOff) {
+        //write to sysfs, one time during this switch
+        const int on = 1;
+        adWrite(on);
+        mTurnedOff = false;
+    }
+
     return true;
 }
 
 bool AssertiveDisplay::draw(hwc_context_t *ctx, int fd, uint32_t offset) {
-    if(!isDoable() || !isModeOn()) {
+    if(!isDoable()) {
         return false;
     }
 
diff --git a/libhwcomposer/hwc_ad.h b/libhwcomposer/hwc_ad.h
index 3bfde17..0be5f5d 100644
--- a/libhwcomposer/hwc_ad.h
+++ b/libhwcomposer/hwc_ad.h
@@ -50,17 +50,16 @@
             mDest = overlay::utils::OV_INVALID;
     }
     bool isDoable() const { return mDoable; }
-    bool isModeOn() const { return (mWbFd >= 0); }
     int getDstFd() const;
     uint32_t getDstOffset() const;
 
 private:
-    //State of feature turned on and off
-    int mWbFd;
     bool mDoable;
+    bool mTurnedOff;
     //State of feature existence on certain devices and configs.
     bool mFeatureEnabled;
     overlay::utils::eDest mDest;
+    void turnOffAD();
 };
 
 }
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 14c478d..540a8e7 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -389,7 +389,8 @@
         ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
         ret = false;
     } else if((qdutils::MDPVersion::getInstance().is8x26() ||
-               qdutils::MDPVersion::getInstance().is8x16()) &&
+               qdutils::MDPVersion::getInstance().is8x16() ||
+               qdutils::MDPVersion::getInstance().is8x39()) &&
             ctx->mVideoTransFlag &&
             isSecondaryConnected(ctx)) {
         //1 Padding round to shift pipes across mixers
@@ -1891,11 +1892,9 @@
             int fd = hnd->fd;
             int offset = (uint32_t)hnd->offset;
 
-            if(ctx->mAD->isModeOn()) {
-                if(ctx->mAD->draw(ctx, fd, offset)) {
-                    fd = ctx->mAD->getDstFd();
-                    offset = ctx->mAD->getDstOffset();
-                }
+            if(ctx->mAD->draw(ctx, fd, offset)) {
+                fd = ctx->mAD->getDstFd();
+                offset = ctx->mAD->getDstOffset();
             }
 
             if(rot) {
diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk
index d8c2ab5..277b44c 100644
--- a/liboverlay/Android.mk
+++ b/liboverlay/Android.mk
@@ -9,9 +9,6 @@
 LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdutils libmemalloc \
                                  libsync libdl
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdoverlay\"
-ifeq ($(TARGET_USES_QSEED_SCALAR),true)
-    LOCAL_CFLAGS += -DUSES_QSEED_SCALAR
-endif
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_SRC_FILES := \
       overlay.cpp \
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 879dde4..5287f02 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -33,11 +33,6 @@
 #include "mdp_version.h"
 #include "qdMetaData.h"
 
-#ifdef USES_QSEED_SCALAR
-#include <scale/scale.h>
-using namespace scale;
-#endif
-
 #define PIPE_DEBUG 0
 
 namespace overlay {
@@ -163,6 +158,8 @@
         return getPipe_8x26(pipeSpecs);
     } else if(MDPVersion::getInstance().is8x16()) {
         return getPipe_8x16(pipeSpecs);
+    } else if(MDPVersion::getInstance().is8x39()) {
+        return getPipe_8x39(pipeSpecs);
     }
 
     eDest dest = OV_INVALID;
@@ -251,6 +248,12 @@
     return dest;
 }
 
+utils::eDest Overlay::getPipe_8x39(const PipeSpecs& pipeSpecs) {
+    //8x16 & 8x36 has same number of pipes, pipe-types & scaling capabilities.
+    //Rely on 8x16 until we see a need to change.
+    return getPipe_8x16(pipeSpecs);
+}
+
 void Overlay::endAllSessions() {
     for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
         if(mPipeBook[i].valid() && mPipeBook[i].mSession==PipeBook::START)
@@ -550,39 +553,20 @@
 }
 
 void Overlay::initScalar() {
-#ifdef USES_QSEED_SCALAR
     if(sLibScaleHandle == NULL) {
         sLibScaleHandle = dlopen("libscale.so", RTLD_NOW);
-    }
-
-    if(sLibScaleHandle) {
-        if(sScale == NULL) {
-            Scale* (*getInstance)();
-            *(void **) &getInstance = dlsym(sLibScaleHandle, "getInstance");
-            if(getInstance) {
-                sScale = getInstance();
-            }
+        if(sLibScaleHandle) {
+            *(void **) &sFnProgramScale =
+                    dlsym(sLibScaleHandle, "programScale");
         }
     }
-#endif
 }
 
 void Overlay::destroyScalar() {
-#ifdef USES_QSEED_SCALAR
     if(sLibScaleHandle) {
-        if(sScale) {
-            void (*destroyInstance)(Scale*);
-            *(void **) &destroyInstance = dlsym(sLibScaleHandle,
-                    "destroyInstance");
-            if(destroyInstance) {
-                destroyInstance(sScale);
-                sScale = NULL;
-            }
-        }
         dlclose(sLibScaleHandle);
         sLibScaleHandle = NULL;
     }
-#endif
 }
 
 void Overlay::PipeBook::init() {
@@ -612,6 +596,6 @@
 utils::eMdpPipeType Overlay::PipeBook::pipeTypeLUT[utils::OV_MAX] =
     {utils::OV_MDP_PIPE_ANY};
 void *Overlay::sLibScaleHandle = NULL;
-scale::Scale *Overlay::sScale = NULL;
+int (*Overlay::sFnProgramScale)(struct mdp_overlay_list *) = NULL;
 
 }; // namespace overlay
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 8c0205c..99186db 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -35,9 +35,6 @@
 #include "utils/threads.h"
 
 struct MetaData_t;
-namespace scale {
-class Scale;
-};
 
 namespace overlay {
 class GenericPipe;
@@ -174,9 +171,10 @@
     /* Helpers that enfore target specific policies while returning pipes */
     utils::eDest getPipe_8x26(const PipeSpecs& pipeSpecs);
     utils::eDest getPipe_8x16(const PipeSpecs& pipeSpecs);
+    utils::eDest getPipe_8x39(const PipeSpecs& pipeSpecs);
 
-    /* Returns the scalar object */
-    static scale::Scale *getScalar();
+    /* Returns the handle to libscale.so's programScale function */
+    static int (*getFnProgramScale())(struct mdp_overlay_list *);
     /* Creates a scalar object using libscale.so */
     static void initScalar();
     /* Destroys the scalar object using libscale.so */
@@ -247,7 +245,7 @@
     static int sDMAMode;
     static bool sDMAMultiplexingSupported;
     static void *sLibScaleHandle;
-    static scale::Scale *sScale;
+    static int (*sFnProgramScale)(struct mdp_overlay_list *);
 
     friend class MdpCtrl;
 };
@@ -321,7 +319,8 @@
 
 inline bool Overlay::isUIScalingOnExternalSupported() {
     if(qdutils::MDPVersion::getInstance().is8x26() or
-       qdutils::MDPVersion::getInstance().is8x16()) {
+       qdutils::MDPVersion::getInstance().is8x16() or
+       qdutils::MDPVersion::getInstance().is8x39()) {
         return false;
     }
     return true;
@@ -336,8 +335,8 @@
     return sDpyFbMap[dpy];
 }
 
-inline scale::Scale *Overlay::getScalar() {
-    return sScale;
+inline int (*Overlay::getFnProgramScale())(struct mdp_overlay_list *) {
+    return sFnProgramScale;
 }
 
 inline bool Overlay::PipeBook::valid() {
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 3af9eaa..c4427ae 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -22,11 +22,6 @@
 #include "mdp_version.h"
 #include <overlay.h>
 
-#ifdef USES_QSEED_SCALAR
-#include <scale/scale.h>
-using namespace scale;
-#endif
-
 #define HSIC_SETTINGS_DEBUG 0
 
 using namespace qdutils;
@@ -371,12 +366,11 @@
     list.num_overlays = count;
     list.overlay_list = ovArray;
 
-#ifdef USES_QSEED_SCALAR
-    Scale *scalar = Overlay::getScalar();
-    if(scalar) {
-        scalar->applyScale(&list);
+   int (*fnProgramScale)(struct mdp_overlay_list *) =
+        Overlay::getFnProgramScale();
+    if(fnProgramScale) {
+        fnProgramScale(&list);
     }
-#endif
 
     if(!mdp_wrapper::validateAndSet(fbFd, list)) {
         /* No dump for failure due to insufficient resource */
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index d1d8355..96ed4d2 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -61,6 +61,12 @@
 #ifndef MDSS_MDP_HW_REV_107
 #define MDSS_MDP_HW_REV_107 0x10070000 //Next version
 #endif
+#ifndef MDSS_MDP_HW_REV_108
+#define MDSS_MDP_HW_REV_108 0x10080000 //8x39 & 8x36
+#endif
+#ifndef MDSS_MDP_HW_REV_109
+#define MDSS_MDP_HW_REV_109 0x10090000 //Next version
+#endif
 #ifndef MDSS_MDP_HW_REV_200
 #define MDSS_MDP_HW_REV_200 0x20000000 //8092
 #endif
@@ -394,5 +400,11 @@
             mMdpRev < MDSS_MDP_HW_REV_107);
 }
 
+bool MDPVersion::is8x39() {
+    return (mMdpRev >= MDSS_MDP_HW_REV_108 and
+            mMdpRev < MDSS_MDP_HW_REV_109);
+}
+
+
 }; //namespace qdutils
 
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 8cc789b..e862d2d 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -146,6 +146,7 @@
     bool is8084();
     bool is8092();
     bool is8x16();
+    bool is8x39();
 
 private:
     bool updateSysFsInfo();