Merge "hwc: Enable PTOR feature for split display"
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 8739f34..4067050 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -44,9 +44,6 @@
     common.module  = const_cast<hw_module_t*>(&module->base.common);
     common.close   = gralloc_close;
     alloc          = gralloc_alloc;
-#ifdef QCOM_BSP
-    allocSize      = gralloc_alloc_size;
-#endif
     free           = gralloc_free;
 
 }
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 0ee69c8..2f2ddc1 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -332,23 +332,6 @@
                 break;
 
             }
-#ifdef QCOM_BSP
-        case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY:
-            {
-                int width = va_arg(args, int);
-                int height = va_arg(args, int);
-                int format = va_arg(args, int);
-                private_handle_t* hnd =  va_arg(args, private_handle_t*);
-                if (private_handle_t::validate(hnd)) {
-                    return res;
-                }
-                hnd->width = width;
-                hnd->height = height;
-                hnd->format = format;
-                res = 0;
-            }
-            break;
-#endif
         case GRALLOC_MODULE_PERFORM_GET_STRIDE:
             {
                 int width   = va_arg(args, int);
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index a5ecb3a..24fd771 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -234,9 +234,6 @@
         finalW = max(finalW, ALIGN((overlap.right - overlap.left), 32));
         finalH += ALIGN((overlap.bottom - overlap.top), 32);
         if(finalH > ALIGN((overlap.bottom - overlap.top), 32)) {
-            // Calculate the offset for RGBA(4BPP)
-            ptorInfo->mRenderBuffOffset[i] = finalW *
-                (finalH - ALIGN((overlap.bottom - overlap.top), 32)) * 4;
             // Calculate the dest top, left will always be zero
             ptorInfo->displayFrame[i].top = (finalH -
                                 (ALIGN((overlap.bottom - overlap.top), 32)));
@@ -276,6 +273,13 @@
         // No copybit device found - cannot use copybit
         return false;
     }
+
+    if(ctx->mThermalBurstMode) {
+        ALOGD_IF (DEBUG_COPYBIT, "%s:Copybit failed,"
+                "Running in Thermal Burst mode",__FUNCTION__);
+        return false;
+    }
+
     int compositionType = qdutils::QCCompositionType::
                                     getInstance().getCompositionType();
 
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 0dec953..863c69e 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -849,18 +849,19 @@
             // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
             continue;
         }
-        // Found the PTOR layer
-        bool found = true;
+        bool found = false;
         for (int j = i-1; j >= 0; j--) {
             // Check if the layers below this layer qualifies for PTOR comp
             hwc_layer_1_t* layer = &list->hwLayers[j];
             hwc_rect_t disFrame = layer->displayFrame;
-            //layer below PTOR is intersecting and has 90 degree transform or
+            // Layer below PTOR is intersecting and has 90 degree transform or
             // needs scaling cannot be supported.
-            if ((isValidRect(getIntersection(dispFrame, disFrame)))
-                            && (has90Transform(layer) || needsScaling(layer))) {
-                found = false;
-                break;
+            if (isValidRect(getIntersection(dispFrame, disFrame))) {
+                if (has90Transform(layer) || needsScaling(layer)) {
+                    found = false;
+                    break;
+                }
+                found = true;
             }
         }
         // Store the minLayer Index
@@ -903,11 +904,30 @@
         sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
     }
 
+    private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
+    Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
+
     for(int j = 0; j < numPTORLayersFound; j++) {
         int index =  ctx->mPtorInfo.layerIndex[j];
+
+        // Update src crop of PTOR layer
+        hwc_layer_1_t* layer = &list->hwLayers[index];
+        layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
+        layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
+        layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
+        layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
+
+        // Store & update w, h, format of PTOR layer
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
+        layerWhf[j] = whf;
+        hnd->width = renderBuf->width;
+        hnd->height = renderBuf->height;
+        hnd->format = renderBuf->format;
+
         // Remove overlap from crop & displayFrame of below layers
         for (int i = 0; i < index && index !=-1; i++) {
-            hwc_layer_1_t* layer = &list->hwLayers[i];
+            layer = &list->hwLayers[i];
             if(!isValidRect(getIntersection(layer->displayFrame,
                                             overlapRect[j])))  {
                 continue;
@@ -944,6 +964,15 @@
         layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
     }
 
+    // Restore w,h,f of PTOR layers
+    for (int i = 0; i < numPTORLayersFound; i++) {
+        int idx = ctx->mPtorInfo.layerIndex[i];
+        private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
+        hnd->width = layerWhf[i].w;
+        hnd->height = layerWhf[i].h;
+        hnd->format = layerWhf[i].format;
+    }
+
     if (!result) {
         // reset PTOR
         ctx->mPtorInfo.count = 0;
@@ -1928,8 +1957,7 @@
             if (!mDpy && (index != -1)) {
                 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
                 fd = hnd->fd;
-                // Use the offset of the RenderBuffer
-                offset = ctx->mPtorInfo.mRenderBuffOffset[index];
+                offset = 0;
             }
 
             ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
@@ -2180,7 +2208,7 @@
             if (!mDpy && (index != -1)) {
                 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
                 fd = hnd->fd;
-                offset = ctx->mPtorInfo.mRenderBuffOffset[index];
+                offset = 0;
             }
 
             if(ctx->mAD->draw(ctx, fd, offset)) {
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 4447cfd..3696c05 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -273,9 +273,15 @@
     //independent process as well.
     QService::init();
     sp<IQClient> client = new QClient(ctx);
-    interface_cast<IQService>(
+    android::sp<qService::IQService> qservice_sp = interface_cast<IQService>(
             defaultServiceManager()->getService(
-            String16("display.qservice")))->connect(client);
+            String16("display.qservice")));
+    if (qservice_sp.get()) {
+      qservice_sp->connect(client);
+    } else {
+      ALOGE("%s: Failed to acquire service pointer", __FUNCTION__);
+      return ;
+    }
 
     // Initialize device orientation to its default orientation
     ctx->deviceOrientation = 0;
@@ -1438,8 +1444,8 @@
         fd = -1;
     }
 
-    if (!dpy && ctx->mCopyBit[dpy]) {
-        if (ctx->mPtorInfo.isActive())
+    if (ctx->mCopyBit[dpy]) {
+        if (!dpy && ctx->mPtorInfo.isActive())
             ctx->mCopyBit[dpy]->setReleaseFdSync(releaseFd);
         else
             ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index dd55f8b..66fdc65 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -137,7 +137,6 @@
 struct PtorInfo {
     int count;
     int layerIndex[MAX_PTOR_LAYERS];
-    int mRenderBuffOffset[MAX_PTOR_LAYERS];
     hwc_rect_t displayFrame[MAX_PTOR_LAYERS];
     bool isActive() { return (count>0); }
     int getPTORArrayIndex(int index) {
@@ -594,6 +593,8 @@
     bool enableABC;
     // PTOR Info
     qhwc::PtorInfo mPtorInfo;
+    //Running in Thermal burst mode
+    bool mThermalBurstMode;
 };
 
 namespace qhwc {
diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp
index 47f2229..6c6ba63 100644
--- a/libhwcomposer/hwc_vsync.cpp
+++ b/libhwcomposer/hwc_vsync.cpp
@@ -39,6 +39,7 @@
 #define MAX_SYSFS_FILE_PATH             255
 #define PANEL_ON_STR "panel_power_on ="
 #define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))
+#define MAX_THERMAL_LEVEL 3
 const int MAX_DATA = 64;
 
 int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable)
@@ -76,6 +77,20 @@
     }
 }
 
+static void handle_thermal_event(hwc_context_t* ctx, int dpy, char *data)
+{
+    // extract thermal level
+    uint64_t thermalLevel = 0;
+    if (!strncmp(data, "thermal_level=", strlen("thermal_level="))) {
+        thermalLevel = strtoull(data + strlen("thermal_level="), NULL, 0);
+    }
+
+    if (thermalLevel >= MAX_THERMAL_LEVEL)
+        ctx->mThermalBurstMode = true;
+    else
+        ctx->mThermalBurstMode = false;
+}
+
 struct event {
     const char* name;
     void (*callback)(hwc_context_t* ctx, int dpy, char *data);
@@ -84,6 +99,7 @@
 struct event event_list[] =  {
     { "vsync_event", handle_vsync_event },
     { "show_blank_event", handle_blank_event },
+    { "msm_fb_thermal_level", handle_thermal_event },
 };
 
 #define num_events ARRAY_LENGTH(event_list)