hwc/qservice: Add support for toggling bwc over binder

Remove support for toggling BWC via property and add support to
toggle BWC over binder. This will take effect only on targets where
the driver enables BWC.

Example to disable BWC:
    adb shell service call display.qservice 17 i32 0
Where 17 is the code to toggle BWC, 0 to disable.

Change-Id: Ie534ab4643a72d47f5a985fe0b32e134bf0e7af3
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index d808a97..9cd99b8 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -2644,7 +2644,8 @@
         ctx->mLayerRotMap[mDpy]->add(layer, *rot);
         //If the video is using a single pipe, enable BWC
         if(rDest == OV_INVALID) {
-            BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
+            BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
+                    mdpFlags);
         }
         //Configure rotator for pre-rotation
         if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 8e8066e..249affc 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -41,6 +41,7 @@
 using namespace qService;
 using namespace qhwc;
 using namespace overlay;
+using namespace qdutils;
 
 namespace qClient {
 
@@ -251,6 +252,17 @@
     MDPComp::setMaxPipesPerMixer(value);
 }
 
+static void toggleBWC(hwc_context_t* ctx, const Parcel* inParcel) {
+    uint32_t enable = (uint32_t)inParcel->readInt32();
+    if(MDPVersion::getInstance().supportsBWC()) {
+        Locker::Autolock _sl(ctx->mDrawLock);
+        ctx->mBWCEnabled = (bool) enable;
+        ALOGI("%s: Set BWC to %d", __FUNCTION__, enable);
+    } else {
+        ALOGI("%s: Target doesn't support BWC", __FUNCTION__);
+    }
+}
+
 status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
         Parcel* outParcel) {
     status_t ret = NO_ERROR;
@@ -299,6 +311,9 @@
         case IQService::SET_MAX_PIPES_PER_MIXER:
             setMaxPipesPerMixer(mHwcContext, inParcel);
             break;
+        case IQService::TOGGLE_BWC:
+            toggleBWC(mHwcContext, inParcel);
+            break;
         default:
             ret = NO_ERROR;
     }
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 2fcf06d..34132eb 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -296,6 +296,7 @@
     ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
     ctx->mOverlay = overlay::Overlay::getInstance();
     ctx->mRotMgr = RotMgr::getInstance();
+    ctx->mBWCEnabled = qdutils::MDPVersion::getInstance().supportsBWC();
 
     //default_app_buffer for ferrum
     if (ctx->mMDP.version ==  qdutils::MDP_V3_0_5) {
@@ -1972,9 +1973,8 @@
         *rot = ctx->mRotMgr->getNext();
         if(*rot == NULL) return -1;
         ctx->mLayerRotMap[dpy]->add(layer, *rot);
-        // BWC is not tested for other formats So enable it only for YUV format
-        if(!dpy && isYuvBuffer(hnd))
-            BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
+        BwcPM::setBwc(ctx, dpy, hnd, crop, dst, transform, downscale,
+                mdpFlags);
         //Configure rotator for pre-rotation
         if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
             ALOGE("%s: configRotator failed!", __FUNCTION__);
@@ -2219,9 +2219,8 @@
         (*rot) = ctx->mRotMgr->getNext();
         if((*rot) == NULL) return -1;
         ctx->mLayerRotMap[dpy]->add(layer, *rot);
-        // BWC is not tested for other formats So enable it only for YUV format
-        if(!dpy && isYuvBuffer(hnd))
-            BwcPM::setBwc(crop, dst, transform, downscale, mdpFlagsL);
+        BwcPM::setBwc(ctx, dpy, hnd, crop, dst, transform, downscale,
+                mdpFlagsL);
         //Configure rotator for pre-rotation
         if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
             ALOGE("%s: configRotator failed!", __FUNCTION__);
@@ -2475,17 +2474,25 @@
     return (eqBounds == 3);
 }
 
-void BwcPM::setBwc(const hwc_rect_t& crop, const hwc_rect_t& dst,
+void BwcPM::setBwc(const hwc_context_t *ctx, const int& dpy,
+        const private_handle_t *hnd,
+        const hwc_rect_t& crop, const hwc_rect_t& dst,
         const int& transform,const int& downscale,
         ovutils::eMdpFlags& mdpFlags) {
-    //BWC not supported with rot-downscale
-    if(downscale) return;
-
     //Target doesnt support Bwc
     qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
-    if(!mdpHw.supportsBWC()) {
+    if(not mdpHw.supportsBWC()) {
         return;
     }
+    //Disabled at runtime
+    if(not ctx->mBWCEnabled) return;
+    //BWC not supported with rot-downscale
+    if(downscale) return;
+    //Not enabled for secondary displays
+    if(dpy) return;
+    //Not enabled for non-video buffers
+    if(not isYuvBuffer(hnd)) return;
+
     int src_w = crop.right - crop.left;
     int src_h = crop.bottom - crop.top;
     int dst_w = dst.right - dst.left;
@@ -2505,10 +2512,6 @@
                 vertDeci);
         if(horzDeci || vertDeci) return;
     }
-    //Property
-    char value[PROPERTY_VALUE_MAX];
-    property_get("debug.disable.bwc", value, "0");
-     if(atoi(value)) return;
 
     ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDSS_MDP_BWC_EN);
 }
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 921c3e5..336bbbb 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -174,7 +174,9 @@
 };
 
 struct BwcPM {
-    static void setBwc(const hwc_rect_t& crop, const hwc_rect_t& dst,
+    static void setBwc(const hwc_context_t *ctx, const int& dpy,
+            const private_handle_t *hnd,
+            const hwc_rect_t& crop, const hwc_rect_t& dst,
             const int& transform, const int& downscale,
             ovutils::eMdpFlags& mdpFlags);
 };
@@ -627,6 +629,8 @@
     // This denotes the tolerance between video layer and external display
     // aspect ratio
     float mAspectRatioToleranceLevel;
+    // Runtime switch for BWC for targets that support it
+    bool mBWCEnabled;
 };
 
 namespace qhwc {
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 6f2f0e3..ea40334 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -39,21 +39,22 @@
     DECLARE_META_INTERFACE(QService);
     enum {
         COMMAND_LIST_START = android::IBinder::FIRST_CALL_TRANSACTION,
-        SECURING,                // Hardware securing start/end notification
-        UNSECURING,              // Hardware unsecuring start/end notification
-        CONNECT,                 // Connect to qservice
-        SCREEN_REFRESH,          // Refresh screen through SF invalidate
-        EXTERNAL_ORIENTATION,    // Set external orientation
-        BUFFER_MIRRORMODE,       // Buffer mirrormode
-        CHECK_EXTERNAL_STATUS,   // Check status of external display
-        GET_DISPLAY_ATTRIBUTES,  // Get display attributes
-        SET_HSIC_DATA,           // Set HSIC on dspp
-        GET_DISPLAY_VISIBLE_REGION,  // Get the visibleRegion for dpy
-        SET_SECONDARY_DISPLAY_STATUS,  // Sets secondary display status
-        SET_MAX_PIPES_PER_MIXER, // Set max pipes per mixer for MDPComp
-        SET_VIEW_FRAME,          // Set view frame of display
-        DYNAMIC_DEBUG,           // Enable more logging on the fly
-        SET_IDLE_TIMEOUT,        // Set idle timeout for GPU fallback
+        SECURING = 2,           // Hardware securing start/end notification
+        UNSECURING = 3,         // Hardware unsecuring start/end notification
+        CONNECT = 4,            // Connect to qservice
+        SCREEN_REFRESH = 5,     // Refresh screen through SF invalidate
+        EXTERNAL_ORIENTATION = 6,// Set external orientation
+        BUFFER_MIRRORMODE = 7,  // Buffer mirrormode
+        CHECK_EXTERNAL_STATUS = 8,// Check status of external display
+        GET_DISPLAY_ATTRIBUTES = 9,// Get display attributes
+        SET_HSIC_DATA = 10,     // Set HSIC on dspp
+        GET_DISPLAY_VISIBLE_REGION = 11,// Get the visibleRegion for dpy
+        SET_SECONDARY_DISPLAY_STATUS = 12,// Sets secondary display status
+        SET_MAX_PIPES_PER_MIXER = 13,// Set max pipes per mixer for MDPComp
+        SET_VIEW_FRAME = 14,    // Set view frame of display
+        DYNAMIC_DEBUG = 15,     // Enable more logging on the fly
+        SET_IDLE_TIMEOUT = 16,  // Set idle timeout for GPU fallback
+        TOGGLE_BWC = 17,           // Toggle BWC On/Off on targets that support
         COMMAND_LIST_END = 400,
     };