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/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(); }