qdutils: metadata utility functions

Add support for copying to/from virtual addresses as well, in
clients which only have the metadata base pointer but not the
native handle

CRs-Fixed: 2033657
Change-Id: I3d4d0e4139207a54c3db2f8585533974e1657a0a
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index f1eece9..ae23b53 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -35,6 +35,10 @@
 #include <gralloc_priv.h>
 #include "qdMetaData.h"
 
+unsigned long getMetaDataSize() {
+    return static_cast<unsigned long>(ROUND_UP_PAGESIZE(sizeof(MetaData_t)));
+}
+
 static int validateAndMap(private_handle_t* handle) {
     if (private_handle_t::validate(handle)) {
         ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
@@ -47,7 +51,7 @@
     }
 
     if (!handle->base_metadata) {
-        unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+        auto size = getMetaDataSize();
         void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
                 handle->fd_metadata, 0);
         if (base == reinterpret_cast<void*>(MAP_FAILED)) {
@@ -62,12 +66,18 @@
 }
 
 int setMetaData(private_handle_t *handle, DispParamType paramType,
-                                                    void *param) {
+                void *param) {
     auto err = validateAndMap(handle);
     if (err != 0)
         return err;
+    return setMetaDataVa(reinterpret_cast<MetaData_t*>(handle->base_metadata),
+                         paramType, param);
+}
 
-    MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
+int setMetaDataVa(MetaData_t *data, DispParamType paramType,
+                  void *param) {
+    if (data == nullptr)
+        return -EINVAL;
     // If parameter is NULL reset the specific MetaData Key
     if (!param) {
        data->operation &= ~paramType;
@@ -126,8 +136,13 @@
     auto err = validateAndMap(handle);
     if (err != 0)
         return err;
+    return clearMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+            paramType);
+}
 
-    MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
+int clearMetaDataVa(MetaData_t *data, DispParamType paramType) {
+    if (data == nullptr)
+        return -EINVAL;
     data->operation &= ~paramType;
     switch (paramType) {
         case SET_S3D_COMP:
@@ -146,9 +161,16 @@
     int ret = validateAndMap(handle);
     if (ret != 0)
         return ret;
-    MetaData_t *data = reinterpret_cast <MetaData_t *>(handle->base_metadata);
+    return getMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
+                         paramType, param);
+}
+
+int getMetaDataVa(MetaData_t *data, DispFetchParamType paramType,
+                  void *param) {
     // Make sure we send 0 only if the operation queried is present
-    ret = -EINVAL;
+    int ret = -EINVAL;
+    if (data == nullptr)
+        return ret;
 
     switch (paramType) {
         case GET_PP_PARAM_INTERLACED:
@@ -241,9 +263,49 @@
     if (err != 0)
         return err;
 
-    unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
     MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
     MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
-    memcpy(src_data, dst_data, size);
+    memcpy(src_data, dst_data, getMetaDataSize());
     return 0;
 }
+
+int copyMetaDataVaToHandle(MetaData_t *src_data, struct private_handle_t *dst) {
+    int err = -EINVAL;
+    if (src_data == nullptr)
+        return err;
+
+    err = validateAndMap(dst);
+    if (err != 0)
+        return err;
+
+    MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
+    memcpy(src_data, dst_data, getMetaDataSize());
+    return 0;
+}
+
+int copyMetaDataHandleToVa(struct private_handle_t *src, MetaData_t *dst_data) {
+    int err = -EINVAL;
+    if (dst_data == nullptr)
+        return err;
+
+    err = validateAndMap(src);
+    if (err != 0)
+        return err;
+
+    MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
+    memcpy(src_data, dst_data, getMetaDataSize());
+    return 0;
+}
+
+int copyMetaDataVaToVa(MetaData_t *src_data, MetaData_t *dst_data) {
+    int err = -EINVAL;
+    if (src_data == nullptr)
+        return err;
+
+    if (dst_data == nullptr)
+        return err;
+
+    memcpy(src_data, dst_data, getMetaDataSize());
+    return 0;
+}
+
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index 042db21..e704f6c 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -177,14 +177,25 @@
 
 struct private_handle_t;
 int setMetaData(struct private_handle_t *handle, enum DispParamType paramType,
-        void *param);
+                void *param);
+int setMetaDataVa(struct MetaData_t* data, enum DispParamType paramType,
+                  void *param);
 
-int getMetaData(struct private_handle_t *handle, enum DispFetchParamType paramType,
-        void *param);
+int getMetaData(struct private_handle_t *handle,
+                enum DispFetchParamType paramType,
+                void *param);
+int getMetaDataVa(struct MetaData_t* data, enum DispFetchParamType paramType,
+                  void *param);
 
 int copyMetaData(struct private_handle_t *src, struct private_handle_t *dst);
+int copyMetaDataVaToHandle(struct MetaData_t *src, struct private_handle_t *dst);
+int copyMetaDataHandleToVa(struct private_handle_t* src, struct MetaData_t *dst);
+int copyMetaDataVaToVa(struct MetaData_t *src, struct MetaData_t *dst);
 
 int clearMetaData(struct private_handle_t *handle, enum DispParamType paramType);
+int clearMetaDataVa(struct MetaData_t *data, enum DispParamType paramType);
+
+unsigned long getMetaDataSize();
 
 #ifdef __cplusplus
 }