hwc/copybit: Handle "R/B swap" for RGBA and RGBX color formats.

1.Framework notifies HAL with "HWC_FORMAT_RB_SWAP" layer flag to handle
a limitation where R and B components were swapped in Rendering phase.
2.Add "R/B swap" in hwc query to enable framework to query for support
in display HAL, at run-time.

Change-Id: I3b44d15b51b4f24939048fee9d1bac2b9009c97c
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index ec12b83..3b7039c 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -126,6 +126,7 @@
     switch (format) {
         case HAL_PIXEL_FORMAT_RGB_565:       return MDP_RGB_565;
         case HAL_PIXEL_FORMAT_RGBX_8888:     return MDP_RGBX_8888;
+        case HAL_PIXEL_FORMAT_BGRX_8888:     return MDP_BGRX_8888;
         case HAL_PIXEL_FORMAT_RGB_888:       return MDP_RGB_888;
         case HAL_PIXEL_FORMAT_RGBA_8888:     return MDP_RGBA_8888;
         case HAL_PIXEL_FORMAT_BGRA_8888:     return MDP_BGRA_8888;
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index a97cced..03d15a7 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -104,6 +104,7 @@
     HAL_PIXEL_FORMAT_YCbCr_444_SP           = 0x10F,
     HAL_PIXEL_FORMAT_YCrCb_444_SP           = 0x110,
     HAL_PIXEL_FORMAT_YCrCb_422_I            = 0x111,
+    HAL_PIXEL_FORMAT_BGRX_8888              = 0x112,
     HAL_PIXEL_FORMAT_INTERLACE              = 0x180,
 
 };
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index ec9abfb..5038025 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -446,6 +446,9 @@
             supported |= HWC_DISPLAY_EXTERNAL_BIT;
         value[0] = supported;
         break;
+    case HWC_FORMAT_RB_SWAP:
+        value[0] = 1;
+        break;
     default:
         return -EINVAL;
     }
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 8f2cf55..ba40db5 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -350,6 +350,16 @@
     src.w = hnd->width;
     src.h = hnd->height;
     src.format = hnd->format;
+
+    // Handle R/B swap
+    if ((layer->flags & HWC_FORMAT_RB_SWAP)) {
+        if (src.format == HAL_PIXEL_FORMAT_RGBA_8888) {
+            src.format = HAL_PIXEL_FORMAT_BGRA_8888;
+        } else if (src.format == HAL_PIXEL_FORMAT_RGBX_8888) {
+            src.format = HAL_PIXEL_FORMAT_BGRX_8888;
+        }
+    }
+
     src.base = (void *)hnd->base;
     src.handle = (native_handle_t *)layer->handle;
     src.horiz_padding = src.w - hnd->width;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 47afa85..e5c5a41 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1385,6 +1385,14 @@
     Whf whf(hnd->width, hnd->height,
             getMdpFormat(hnd->format), hnd->size);
 
+    // Handle R/B swap
+    if (layer->flags & HWC_FORMAT_RB_SWAP) {
+        if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
+            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
+        else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
+            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
+    }
+
     if(dpy && isYuvBuffer(hnd)) {
         if(!ctx->listStats[dpy].isDisplayAnimating) {
             ctx->mPrevCropVideo = crop;
@@ -1508,6 +1516,14 @@
     Whf whf(hnd->width, hnd->height,
             getMdpFormat(hnd->format), hnd->size);
 
+    // Handle R/B swap
+    if (layer->flags & HWC_FORMAT_RB_SWAP) {
+        if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
+            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
+        else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
+            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
+    }
+
     if(dpy && isYuvBuffer(hnd)) {
         if(!ctx->listStats[dpy].isDisplayAnimating) {
             ctx->mPrevCropVideo = crop;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 3b5d3cb..8fb62a0 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -127,6 +127,11 @@
     HWC_COPYBIT = 0x00000002,
 };
 
+// HAL specific features
+enum {
+    HWC_FORMAT_RB_SWAP = 0x00000040,
+};
+
 class LayerRotMap {
 public:
     LayerRotMap() { reset(); }
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index df2c09e..fd8bfe2 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -100,6 +100,8 @@
             return MDP_RGB_565;
         case HAL_PIXEL_FORMAT_BGRA_8888:
             return MDP_BGRA_8888;
+        case HAL_PIXEL_FORMAT_BGRX_8888:
+            return MDP_BGRX_8888;
         case HAL_PIXEL_FORMAT_YV12:
             return MDP_Y_CR_CB_GH2V2;
         case HAL_PIXEL_FORMAT_YCbCr_422_SP: