Gralloc: Use adreno APIs for buffer size calculations

1) Add support to use adreno APIs for non video layers'
buffer size calculations.
2) Add graphics metadata field to MetaData_t structure.
3) Add bindings for newly introduced formats in
GetGpuPixelFormat.
4) Add support to retrieve the graphics metadata in
Perform API.
5) Modify BUFFER_TYPE determination logic

Change-Id: I7674209b42d7cd39bc8de39e3a10582bb216e6cf
CRs-Fixed: 2226672
diff --git a/gralloc/gr_adreno_info.cpp b/gralloc/gr_adreno_info.cpp
index 2e1245c..1288d92 100644
--- a/gralloc/gr_adreno_info.cpp
+++ b/gralloc/gr_adreno_info.cpp
@@ -68,6 +68,12 @@
         ::dlsym(libadreno_utils_, "isUBWCSupportedByGpu");
     *reinterpret_cast<void **>(&LINK_adreno_get_gpu_pixel_alignment) =
         ::dlsym(libadreno_utils_, "get_gpu_pixel_alignment");
+    *reinterpret_cast<void **>(&LINK_adreno_get_metadata_blob_size) =
+        ::dlsym(libadreno_utils_, "adreno_get_metadata_blob_size");
+    *reinterpret_cast<void **>(&LINK_adreno_init_memory_layout) =
+        ::dlsym(libadreno_utils_, "adreno_init_memory_layout");
+    *reinterpret_cast<void **>(&LINK_adreno_get_aligned_gpu_buffer_size) =
+        ::dlsym(libadreno_utils_, "adreno_get_aligned_gpu_buffer_size");
   } else {
     ALOGE(" Failed to load libadreno_utils.so");
   }
@@ -181,7 +187,7 @@
     case HAL_PIXEL_FORMAT_RGBX_8888:
       return ADRENO_PIXELFORMAT_R8G8B8X8;
     case HAL_PIXEL_FORMAT_BGRA_8888:
-      return ADRENO_PIXELFORMAT_B8G8R8A8;
+      return ADRENO_PIXELFORMAT_B8G8R8A8_UNORM;
     case HAL_PIXEL_FORMAT_RGB_888:
       return ADRENO_PIXELFORMAT_R8G8B8;
     case HAL_PIXEL_FORMAT_RGB_565:
@@ -211,6 +217,18 @@
     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
       return ADRENO_PIXELFORMAT_P010;
+    case HAL_PIXEL_FORMAT_DEPTH_16:
+      return ADRENO_PIXELFORMAT_D16_UNORM;
+    case HAL_PIXEL_FORMAT_DEPTH_24:
+      return ADRENO_PIXELFORMAT_D24_UNORM;
+    case HAL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
+      return ADRENO_PIXELFORMAT_D24_UNORM_S8_UINT;
+    case HAL_PIXEL_FORMAT_DEPTH_32F:
+      return ADRENO_PIXELFORMAT_D32_FLOAT;
+    case HAL_PIXEL_FORMAT_DEPTH_32F_STENCIL_8:
+      return ADRENO_PIXELFORMAT_D32_FLOAT_X24S8_UINT;
+    case HAL_PIXEL_FORMAT_STENCIL_8:
+      return ADRENO_PIXELFORMAT_S8_UINT;
     default:
       ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
       break;
@@ -219,4 +237,34 @@
   return ADRENO_PIXELFORMAT_UNKNOWN;
 }
 
+uint32_t AdrenoMemInfo::AdrenoGetMetadataBlobSize() {
+  if (LINK_adreno_get_metadata_blob_size) {
+    return LINK_adreno_get_metadata_blob_size();
+  }
+  return 0;
+}
+
+int AdrenoMemInfo::AdrenoInitMemoryLayout(void *metadata_blob, int width, int height, int depth,
+  int format, int num_samples, int isUBWC, uint64_t usage, uint32_t num_planes) {
+  if (LINK_adreno_init_memory_layout) {
+    surface_tile_mode_t tile_mode = static_cast<surface_tile_mode_t> (isUBWC);
+    return LINK_adreno_init_memory_layout(metadata_blob, width, height, depth,
+                                          GetGpuPixelFormat(format), num_samples,
+                                          tile_mode, usage, num_planes);
+  }
+  return -1;
+}
+
+uint32_t AdrenoMemInfo::AdrenoGetAlignedGpuBufferSize(void *metadata_blob) {
+  if (LINK_adreno_get_aligned_gpu_buffer_size) {
+    return LINK_adreno_get_aligned_gpu_buffer_size(metadata_blob);
+  }
+  return -1;
+}
+
+bool AdrenoMemInfo::AdrenoSizeAPIAvaliable() {
+  return (LINK_adreno_get_metadata_blob_size && LINK_adreno_init_memory_layout &&
+          LINK_adreno_get_aligned_gpu_buffer_size);
+}
+
 }  // namespace gralloc
diff --git a/gralloc/gr_adreno_info.h b/gralloc/gr_adreno_info.h
index b85e7c1..eec7da4 100644
--- a/gralloc/gr_adreno_info.h
+++ b/gralloc/gr_adreno_info.h
@@ -41,8 +41,12 @@
   ADRENO_PIXELFORMAT_R10G10B10A2_UNORM = 24,  // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
   ADRENO_PIXELFORMAT_R8G8B8A8 = 28,
   ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
+  ADRENO_PIXELFORMAT_D32_FLOAT = 40,
+  ADRENO_PIXELFORMAT_D24_UNORM_S8_UINT = 45,
+  ADRENO_PIXELFORMAT_D16_UNORM = 55,
   ADRENO_PIXELFORMAT_B5G6R5 = 85,
   ADRENO_PIXELFORMAT_B5G5R5A1 = 86,
+  ADRENO_PIXELFORMAT_B8G8R8A8_UNORM = 87,
   ADRENO_PIXELFORMAT_B8G8R8A8 = 90,
   ADRENO_PIXELFORMAT_B8G8R8A8_SRGB = 91,
   ADRENO_PIXELFORMAT_B8G8R8X8_SRGB = 93,
@@ -59,6 +63,9 @@
   ADRENO_PIXELFORMAT_A2B10G10R10_UNORM = 532,
   // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
   ADRENO_PIXELFORMAT_R10G10B10X2_UNORM = 537,
+  ADRENO_PIXELFORMAT_D24_UNORM = 549,
+  ADRENO_PIXELFORMAT_D32_FLOAT_X24S8_UINT = 551,
+  ADRENO_PIXELFORMAT_S8_UINT = 552,
   // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
   ADRENO_PIXELFORMAT_R5G6B5 = 610,    //  RGBA version of B5G6R5
   ADRENO_PIXELFORMAT_R5G5B5A1 = 611,  //  RGBA version of B5G5R5A1
@@ -70,6 +77,11 @@
   ADRENO_PIXELFORMAT_TP10 = 654,      // YUV 4:2:0 planar 10 bits/comp (2 planes)
 } ADRENOPIXELFORMAT;
 
+typedef enum {
+  SURFACE_TILE_MODE_DISABLE    = 0x0,    // used for linear surface
+  SURFACE_TILE_MODE_ENABLE     = 0x1     // used for tiled surface
+} surface_tile_mode_t;
+
 class AdrenoMemInfo {
  public:
   /*
@@ -119,6 +131,32 @@
    */
   ADRENOPIXELFORMAT GetGpuPixelFormat(int hal_format);
 
+  /*
+   * Function to get graphics metadata blob size
+   * @return graphics metadata size
+   */
+  uint32_t AdrenoGetMetadataBlobSize();
+
+  /*
+   * Function to populate the graphics metadata blob
+   * @return 1 : Successful
+   *         2 : Unsuccessful
+   */
+  int AdrenoInitMemoryLayout(void *metadata_blob, int width, int height, int depth, int format,
+                             int num_samples, int isUBWC, uint64_t usage, uint32_t num_planes);
+  /*
+   * Function to get buffer size for based on graphcis metadata
+   * @return buffer size
+   */
+  uint32_t AdrenoGetAlignedGpuBufferSize(void *metadata_blob);
+
+  /*
+   * Function to check if adreno size calculation APIs are avaliable
+   * @return true  : Avaliable
+   *         false : Unavaliable
+  */
+  bool AdrenoSizeAPIAvaliable();
+
   static AdrenoMemInfo *GetInstance();
 
  private:
@@ -142,6 +180,12 @@
   int (*LINK_adreno_isUBWCSupportedByGpu)(ADRENOPIXELFORMAT format) = NULL;
   unsigned int (*LINK_adreno_get_gpu_pixel_alignment)() = NULL;
 
+  uint32_t (*LINK_adreno_get_metadata_blob_size)() = NULL;
+  int (*LINK_adreno_init_memory_layout)(void* metadata_blob, int width, int height, int depth,
+       ADRENOPIXELFORMAT format, int num_samples, surface_tile_mode_t tile_mode,
+       uint64_t usage, uint32_t num_planes) = NULL;
+  uint32_t (*LINK_adreno_get_aligned_gpu_buffer_size)(void* metadata_blob) = NULL;
+
   bool gfx_ubwc_disable_ = false;
   void *libadreno_utils_ = NULL;
 
diff --git a/gralloc/gr_buf_mgr.cpp b/gralloc/gr_buf_mgr.cpp
index 5e1973e..5cf18aa 100644
--- a/gralloc/gr_buf_mgr.cpp
+++ b/gralloc/gr_buf_mgr.cpp
@@ -301,10 +301,10 @@
 }
 
 int BufferManager::GetBufferType(int inputFormat) {
-  int buffer_type = BUFFER_TYPE_VIDEO;
-  if (IsUncompressedRGBFormat(inputFormat)) {
-    // RGB formats
-    buffer_type = BUFFER_TYPE_UI;
+  int buffer_type = BUFFER_TYPE_UI;
+  if (IsYuvFormat(inputFormat)) {
+    // Video format
+    buffer_type = BUFFER_TYPE_VIDEO;
   }
 
   return buffer_type;
@@ -326,9 +326,18 @@
   int buffer_type = GetBufferType(format);
   BufferInfo info = GetBufferInfo(descriptor);
   info.format = format;
-  GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
-  size = (bufferSize >= size) ? bufferSize : size;
 
+  bool use_adreno_for_size = false;
+  GraphicsMetadata graphics_metadata = {};
+
+  use_adreno_for_size = ((buffer_type != BUFFER_TYPE_VIDEO) && GetAdrenoSizeAPIStatus());
+  if (use_adreno_for_size) {
+    GetGpuResourceSizeAndDimensions(info, &size, &alignedw, &alignedh, &graphics_metadata);
+  } else {
+    GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
+  }
+
+  size = (bufferSize >= size) ? bufferSize : size;
   int err = 0;
   int flags = 0;
   auto page_size = UINT(getpagesize());
@@ -373,6 +382,10 @@
   ColorSpace_t colorSpace = (buffer_type == BUFFER_TYPE_VIDEO) ? ITU_R_601 : ITU_R_709;
   setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
 
+  if (use_adreno_for_size) {
+    setMetaData(hnd, SET_GRAPHICS_METADATA, reinterpret_cast<void *>(&graphics_metadata));
+  }
+
   *handle = hnd;
   RegisterHandleLocked(hnd, data.ion_handle, e_data.ion_handle);
   ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
diff --git a/gralloc/gr_device_impl.cpp b/gralloc/gr_device_impl.cpp
index a26ea81..61ec38b 100644
--- a/gralloc/gr_device_impl.cpp
+++ b/gralloc/gr_device_impl.cpp
@@ -510,7 +510,7 @@
 
 gralloc1_error_t GrallocImpl::GetFlexLayout(const private_handle_t *hnd,
                                             struct android_flex_layout *layout) {
-  if (!IsYuvFormat(hnd)) {
+  if (!IsYuvFormat(hnd->format)) {
     return GRALLOC1_ERROR_UNSUPPORTED;
   }
 
@@ -560,7 +560,7 @@
   gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
   if (status == GRALLOC1_ERROR_NONE) {
     const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
-    if (!IsYuvFormat(hnd)) {
+    if (!IsYuvFormat(hnd->format)) {
       status = GRALLOC1_ERROR_UNSUPPORTED;
     } else {
       *out_num_planes = 3;
@@ -847,6 +847,21 @@
       }
     } break;
 
+    case GRALLOC_MODULE_PERFORM_GET_GRAPHICS_METADATA: {
+      private_handle_t* hnd = va_arg(args, private_handle_t *);
+
+      if (private_handle_t::validate(hnd) != 0) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+      }
+
+      void* graphic_metadata = va_arg(args, void*);
+
+      if (getMetaData(hnd, GET_GRAPHICS_METADATA, graphic_metadata) != 0) {
+        graphic_metadata = NULL;
+        return GRALLOC1_ERROR_UNSUPPORTED;
+      }
+    } break;
+
     default:
       break;
   }
diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp
index f7ddac6..0436c2a 100644
--- a/gralloc/gr_utils.cpp
+++ b/gralloc/gr_utils.cpp
@@ -32,7 +32,6 @@
 
 #include "gr_adreno_info.h"
 #include "gr_utils.h"
-#include "qdMetaData.h"
 
 #define ASTC_BLOCK_SIZE 16
 
@@ -42,8 +41,8 @@
 
 namespace gralloc {
 
-bool IsYuvFormat(const private_handle_t *hnd) {
-  switch (hnd->format) {
+bool IsYuvFormat(int format) {
+  switch (format) {
     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
@@ -64,6 +63,9 @@
     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
+    // Below formats used by camera and VR
+    case HAL_PIXEL_FORMAT_BLOB:
+    case HAL_PIXEL_FORMAT_RAW_OPAQUE:
       return true;
     default:
       return false;
@@ -943,4 +945,39 @@
   return 0;
 }
 
+void GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
+                                     unsigned int *alignedw, unsigned int *alignedh,
+                                     GraphicsMetadata *graphics_metadata) {
+  GetAlignedWidthAndHeight(info, alignedw, alignedh);
+  AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
+  graphics_metadata->size = adreno_mem_info->AdrenoGetMetadataBlobSize();
+  uint64_t adreno_usage = info.usage;
+  // If gralloc disables UBWC based on any of the checks,
+  // we pass modified usage flag to adreno to convey this.
+  int is_ubwc_enabled = IsUBwcEnabled(info.format, info.usage);
+  if (!is_ubwc_enabled) {
+    adreno_usage &= ~(GRALLOC_USAGE_PRIVATE_ALLOC_UBWC);
+  }
+
+  // Call adreno api for populating metadata blob
+  int ret = adreno_mem_info->AdrenoInitMemoryLayout(graphics_metadata->data, info.width,
+                                                    info.height, 1, info.format, 1,
+                                                    is_ubwc_enabled, adreno_usage, 1);
+  if (ret != 0) {
+    ALOGE("%s Graphics metadata init failed", __FUNCTION__);
+    *size = 0;
+    return;
+  }
+  // Call adreno api with the metadata blob to get buffer size
+  *size = adreno_mem_info->AdrenoGetAlignedGpuBufferSize(graphics_metadata->data);
+}
+
+bool GetAdrenoSizeAPIStatus() {
+  AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
+  if (adreno_mem_info) {
+    return adreno_mem_info->AdrenoSizeAPIAvaliable();
+  }
+  return false;
+}
+
 }  // namespace gralloc
diff --git a/gralloc/gr_utils.h b/gralloc/gr_utils.h
index 783453f..fa62871 100644
--- a/gralloc/gr_utils.h
+++ b/gralloc/gr_utils.h
@@ -32,6 +32,7 @@
 
 #include <android/hardware/graphics/common/1.1/types.h>
 #include "gralloc_priv.h"
+#include "qdMetaData.h"
 
 #define SZ_2M 0x200000
 #define SZ_1M 0x100000
@@ -67,7 +68,7 @@
   return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1));
 }
 
-bool IsYuvFormat(const private_handle_t *hnd);
+bool IsYuvFormat(int format);
 bool IsCompressedRGBFormat(int format);
 bool IsUncompressedRGBFormat(int format);
 uint32_t GetBppForUncompressedRGB(int format);
@@ -102,6 +103,10 @@
                     uint32_t *num_planes);
 uint32_t GetDataAlignment(int format, uint64_t usage);
 
+void GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
+                                     unsigned int *alignedw, unsigned int *alignedh,
+                                     GraphicsMetadata *graphics_metadata);
+bool GetAdrenoSizeAPIStatus();
 }  // namespace gralloc
 
 #endif  // __GR_UTILS_H__
diff --git a/gralloc/gralloc_priv.h b/gralloc/gralloc_priv.h
index b69ce2d..20fe59b 100644
--- a/gralloc/gralloc_priv.h
+++ b/gralloc/gralloc_priv.h
@@ -97,6 +97,7 @@
 #define GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE 13
 #define GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS 14
 #define GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG 15
+#define GRALLOC_MODULE_PERFORM_GET_GRAPHICS_METADATA 16
 
 // OEM specific HAL formats
 #define HAL_PIXEL_FORMAT_RGBA_5551 6