Gralloc: Implement getCustomFormatFlags API

Implement API to get custom format and private handle flags
based on a given combination of input format and usage flags.

Change-Id: Id87e9abe834fb17c6304262cc486a84131c8809a
CRs-Fixed: 2255171
diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp
index a49f1ea..282bcc2 100644
--- a/gralloc/gr_utils.cpp
+++ b/gralloc/gr_utils.cpp
@@ -543,6 +543,28 @@
   return false;
 }
 
+bool IsUBwcPISupported(int format, uint64_t usage) {
+  if (usage & BufferUsage::COMPOSER_OVERLAY || !(usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI)) {
+    return false;
+  }
+
+  // As of now only two formats
+  switch (format) {
+    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: {
+      if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
+        if (AdrenoMemInfo::GetInstance()) {
+          return AdrenoMemInfo::GetInstance()->IsPISupportedByGPU(format, usage);
+        }
+      } else {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
 bool IsUBwcEnabled(int format, uint64_t usage) {
   // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
   if (IsUBwcFormat(format)) {
@@ -552,7 +574,8 @@
   // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
   // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
   // usage flag and MDP supports the format.
-  if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
+  if (((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) || (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI))
+        && IsUBwcSupported(format)) {
     bool enable = true;
     // Query GPU for UBWC only if buffer is intended to be used by GPU.
     if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
@@ -983,4 +1006,142 @@
   return false;
 }
 
+bool UseUncached(int format, uint64_t usage) {
+  if ((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) || (usage & BufferUsage::PROTECTED)) {
+    return true;
+  }
+
+  // CPU read rarely
+  if ((usage & BufferUsage::CPU_READ_MASK) == static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY)) {
+    return true;
+  }
+
+  // CPU  write rarely
+  if ((usage & BufferUsage::CPU_WRITE_MASK) ==
+      static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY)) {
+    return true;
+  }
+
+  if ((usage & BufferUsage::SENSOR_DIRECT_DATA) || (usage & BufferUsage::GPU_DATA_BUFFER)) {
+    return true;
+  }
+
+  if (format && IsUBwcEnabled(format, usage)) {
+    return true;
+  }
+
+  return false;
+}
+
+uint64_t GetHandleFlags(int format, uint64_t usage) {
+  uint64_t priv_flags = 0;
+
+  if (usage & BufferUsage::VIDEO_ENCODER) {
+    priv_flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
+  }
+
+  if (usage & BufferUsage::CAMERA_OUTPUT) {
+    priv_flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
+  }
+
+  if (usage & BufferUsage::CAMERA_INPUT) {
+    priv_flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
+  }
+
+  if (usage & BufferUsage::COMPOSER_OVERLAY) {
+    priv_flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
+  }
+
+  if (usage & BufferUsage::GPU_TEXTURE) {
+    priv_flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
+  }
+
+  if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
+    priv_flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
+  }
+
+  if (IsUBwcEnabled(format, usage)) {
+    if (IsUBwcPISupported(format, usage)) {
+      priv_flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI;
+    } else {
+      priv_flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+    }
+  }
+
+  if (usage & (BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK)) {
+    priv_flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
+  }
+
+  if ((usage & (BufferUsage::VIDEO_ENCODER | BufferUsage::VIDEO_DECODER |
+                BufferUsage::CAMERA_OUTPUT | BufferUsage::GPU_RENDER_TARGET))) {
+    priv_flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
+  }
+
+  if (!UseUncached(format, usage)) {
+    priv_flags |= private_handle_t::PRIV_FLAGS_CACHED;
+  }
+
+  return priv_flags;
+}
+
+int GetImplDefinedFormat(uint64_t usage, int format) {
+  int gr_format = format;
+
+  // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
+  // the usage bits, gralloc assigns a format.
+  if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
+      format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+    if (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC || usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI) {
+      // Use of 10BIT_TP and 10BIT bits is supposed to be mutually exclusive.
+      // Each bit maps to only one format. Here we will check one of the bits
+      // and ignore the other.
+      if (usage & GRALLOC_USAGE_PRIVATE_10BIT_TP) {
+        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
+      } else if (usage & GRALLOC_USAGE_PRIVATE_10BIT) {
+        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
+      } else {
+        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+      }
+    } else if (usage & GRALLOC_USAGE_PRIVATE_10BIT) {
+      gr_format = HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS;
+    } else if (usage & BufferUsage::VIDEO_ENCODER) {
+      if (usage & GRALLOC_USAGE_PRIVATE_VIDEO_NV21_ENCODER) {
+        gr_format = HAL_PIXEL_FORMAT_NV21_ENCODEABLE;  // NV21
+      } else {
+        gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;  // NV12
+      }
+    } else if (usage & BufferUsage::CAMERA_INPUT) {
+      if (usage & BufferUsage::CAMERA_OUTPUT) {
+        // Assumed ZSL if both producer and consumer camera flags set
+        gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
+      } else {
+        gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;  // NV21
+      }
+    } else if (usage & BufferUsage::CAMERA_OUTPUT) {
+      if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+        gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
+      } else {
+        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;  // NV12 preview
+      }
+    } else if (usage & BufferUsage::COMPOSER_OVERLAY) {
+      // XXX: If we still haven't set a format, default to RGBA8888
+      gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
+    } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+      // If no other usage flags are detected, default the
+      // flexible YUV format to NV21_ZSL
+      gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
+    }
+  }
+
+  return gr_format;
+}
+
+int GetCustomFormatFlags(int format, uint64_t usage,
+                        int *custom_format, uint64_t *priv_flags) {
+  *custom_format = GetImplDefinedFormat(usage, format);
+  *priv_flags = GetHandleFlags(*custom_format, usage);
+
+  return 0;
+}
+
 }  // namespace gralloc