gralloc: Add gralloc perform api to query RGB data address

A client can call GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS api
to get RGB data address for any linear or UBWC aligned RGB buffer.

Change-Id: I3a7d25f504b7ba1dec79cc872cafbb38ddbb6bd2
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 3e17061..4639e23 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -908,3 +908,38 @@
     }
     return size;
 }
+
+int getRgbDataAddress(private_handle_t* hnd, void* rgb_data)
+{
+    int err = 0;
+
+    // This api is for RGB* formats
+    if (hnd->format > HAL_PIXEL_FORMAT_sRGB_X_8888) {
+        return -EINVAL;
+    }
+
+    // linear buffer
+    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
+        rgb_data = (void*)hnd->base;
+        return err;
+    }
+
+    unsigned int meta_size = 0;
+    switch (hnd->format) {
+        case HAL_PIXEL_FORMAT_RGB_565:
+            meta_size = getUBwcMetaBufferSize(hnd->width, hnd->height, 2);
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_sRGB_A_8888:
+            meta_size = getUBwcMetaBufferSize(hnd->width, hnd->height, 4);
+            break;
+        default:
+            ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
+            err = -EINVAL;
+            break;
+    }
+
+    rgb_data = (void*)(hnd->base + meta_size);
+    return err;
+}
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 5ee0cf8..7dbf6c5 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -71,6 +71,7 @@
 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage);
 void free_buffer(private_handle_t *hnd);
 int getYUVPlaneInfo(private_handle_t* pHnd, struct android_ycbcr* ycbcr);
+int getRgbDataAddress(private_handle_t* pHnd, void* rgb_data);
 
 // To query if UBWC is enabled, based on format and usage flags
 bool isUBwcEnabled(int format, int usage);
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 676c3bc..6998296 100755
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -85,6 +85,7 @@
 #define GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO 7
 #define GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO 8
 #define GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG 9
+#define GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS 10
 
 /* OEM specific HAL formats */
 
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index acac5b4..4a1b2cd 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -457,6 +457,15 @@
                 res = 0;
             } break;
 
+        case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS:
+            {
+                private_handle_t* hnd = va_arg(args, private_handle_t*);
+                void* rgb_data = va_arg(args, void*);
+                if (!private_handle_t::validate(hnd)) {
+                    res = getRgbDataAddress(hnd, rgb_data);
+                }
+            } break;
+
         default:
             break;
     }