sdm: Add support for LINEAR_FORMAT metadata operation

1. Define LINEAR_FORMAT operation in MetaData.
2. VENUS ouput buffer is linear for NV12_UBWC Interlaced video playback.
   So Video module performs LINEAR_FORMAT operation to set "linearFormat"
   metadata member to NV12 linear format in case of Interlaced video.
3. Handle LINEAR_FORMAT metadata operation in HWC wrapper and gralloc.

CRs-Fixed: 855474

Change-Id: I77dd72bec26f225de75adb6c214ccd90db239e3e
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 4ef4886..98079c2 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -655,21 +655,27 @@
     int err = 0;
     int width = hnd->width;
     int height = hnd->height;
+    int format = hnd->format;
     unsigned int ystride, cstride;
     unsigned int alignment = 4096;
 
     memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+
+    // Check if UBWC buffer has been rendered in linear format.
+    if (metadata && (metadata->operation & LINEAR_FORMAT)) {
+        format = metadata->linearFormat;
+    }
 
     // Check metadata if the geometry has been updated.
-    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
     if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
         AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
-                   metadata->bufferDim.sliceHeight, hnd->format, 0, width, height);
+                   metadata->bufferDim.sliceHeight, format, 0, width, height);
     }
 
     // Get the chroma offsets from the handle width/height. We take advantage
     // of the fact the width _is_ the stride
-    switch (hnd->format) {
+    switch (format) {
         //Semiplanar
         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
@@ -745,8 +751,7 @@
         case HAL_PIXEL_FORMAT_YCrCb_422_I:
         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
         default:
-        ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
-                hnd->format);
+        ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
         err = -EINVAL;
     }
     return err;
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index cf365ce..3cfdc55 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -440,6 +440,10 @@
                     return res;
                 }
                 *flag = hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+                MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+                if (metadata && (metadata->operation & LINEAR_FORMAT)) {
+                    *flag = 0;
+                }
                 res = 0;
             } break;
 
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index aae0a47..2aa4a31 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -96,6 +96,9 @@
         case S3D_FORMAT:
             data->s3dFormat = *((uint32_t *)param);
             break;
+        case LINEAR_FORMAT:
+            data->linearFormat = *((uint32_t *)param);
+            break;
         default:
             ALOGE("Unknown paramType %d", paramType);
             break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index a1afa38..7688444 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -89,6 +89,8 @@
     /* The supported formats are defined in gralloc_priv.h to
      * support legacy code*/
     uint32_t s3dFormat;
+    /* VENUS output buffer is linear for UBWC Interlaced video */
+    uint32_t linearFormat;
 };
 
 enum DispParamType {
@@ -104,6 +106,7 @@
     UPDATE_COLOR_SPACE = 0x0200,
     MAP_SECURE_BUFFER = 0x400,
     S3D_FORMAT = 0x800,
+    LINEAR_FORMAT = 0x1000,
 };
 
 struct private_handle_t;
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index 6352a4a..07af737 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -425,7 +425,14 @@
   LayerBuffer *layer_buffer = layer->input_buffer;
 
   if (pvt_handle) {
+    layer->frame_rate = fps;
     layer_buffer->format = GetSDMFormat(pvt_handle->format, pvt_handle->flags);
+
+    const MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata);
+    if (meta_data && (SetMetaData(*meta_data, layer) != kErrorNone)) {
+      return -EINVAL;
+    }
+
     if (layer_buffer->format == kFormatInvalid) {
       return -EINVAL;
     }
@@ -440,13 +447,6 @@
       layer_stack_.flags.secure_present = true;
       layer_buffer->flags.secure = true;
     }
-
-    layer->frame_rate = fps;
-    const MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata);
-    if (meta_data && (SetMetaData(*meta_data, layer) != kErrorNone)) {
-      return -EINVAL;
-    }
-
     if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_DISPLAY) {
       layer_buffer->flags.secure_display = true;
     }
@@ -1207,6 +1207,10 @@
     layer->input_buffer->flags.interlace = true;
   }
 
+  if (meta_data.operation & LINEAR_FORMAT) {
+    layer->input_buffer->format = GetSDMFormat(meta_data.linearFormat, 0);
+  }
+
   if (meta_data.operation & UPDATE_COLOR_SPACE) {
     if (SetColorSpace(meta_data.colorSpace, &layer->color_space) != kErrorNone) {
       return kErrorNotSupported;