Merge "composer: Add lock for callback functions" into rvc-d1-dev
diff --git a/composer/hwc_display_builtin.cpp b/composer/hwc_display_builtin.cpp
index 58d25c6..5ddda56 100644
--- a/composer/hwc_display_builtin.cpp
+++ b/composer/hwc_display_builtin.cpp
@@ -28,17 +28,18 @@
 */
 
 #include <cutils/properties.h>
-#include <sync/sync.h>
+#include <cutils/sockets.h>
 #include <utils/constants.h>
 #include <utils/debug.h>
 #include <utils/utils.h>
 #include <stdarg.h>
+#include <sync/sync.h>
 #include <sys/mman.h>
 
 #include <map>
+#include <iostream>
 #include <string>
 #include <vector>
-#include <cutils/sockets.h>
 
 #include "hwc_display_builtin.h"
 #include "hwc_debugger.h"
@@ -59,52 +60,26 @@
 
 static std::string LoadPanelGammaCalibration() {
   constexpr char file[] = "/mnt/vendor/persist/display/gamma_calib_data.cal";
-  int fd = open(file, O_RDONLY);
-  if (fd < 0) {
+  std::ifstream fin(file);
+
+  if (!fin.is_open()) {
     DLOGW("Unable to open gamma calibration '%s', error = %s", file, strerror(errno));
     return {};
   }
 
-  struct stat info;
-  if (fstat(fd, &info) == -1) {
-    DLOGE("Unable to stat gamma calibration '%s', error = %s", file, strerror(errno));
-    close(fd);
-    return {};
+  std::string data, gamma;
+  while (std::getline(fin, data)) {
+    gamma.append(data.c_str());
+    gamma.append(" ");
+  }
+  fin.close();
+
+  /* eliminate space character in the last byte */
+  if (!gamma.empty()) {
+    gamma.pop_back();
   }
 
-  std::vector<char> buf(info.st_size);
-  char *ptr = buf.data();
-  ssize_t len;
-  while (((len = read(fd, ptr, info.st_size - (ptr - buf.data()))) != 0)) {
-    if (len > 0) {
-      ptr += len;
-    } else if ((errno != EINTR) && (errno != EAGAIN)) {
-      break;
-    }
-  }
-  close(fd);
-
-  if (len == 0) {
-    char *token, *saveptr = nullptr;
-    const char *delim = "\r\n";
-    std::string gamma;
-
-    token = strtok_r(buf.data(), delim, &saveptr);
-    while (token) {
-      gamma.append(token);
-      gamma.append(" ");
-      token = strtok_r(NULL, delim, &saveptr);
-    }
-
-    if (!gamma.empty()) {
-      gamma.pop_back();
-    }
-
-    return gamma;
-  } else {
-    DLOGE("Failed to read gamma calibration data, error = %s", strerror(errno));
-    return {};
-  }
+  return gamma;
 }
 
 static DisplayError WritePanelGammaTableToDriver(const std::string &gamma_data) {
diff --git a/gralloc/QtiMapper4.h b/gralloc/QtiMapper4.h
index 9d3b20c..937b3cf 100644
--- a/gralloc/QtiMapper4.h
+++ b/gralloc/QtiMapper4.h
@@ -149,9 +149,7 @@
     std::memcpy(&out[index], &bd_info.usage, sizeof(bd_info.usage));
     index += sizeof(bd_info.usage);
 
-    // Cap the reserved region size at one page (4096 bytes)
-    uint64_t reserved_size = std::min(bd_info.reservedSize, (uint64_t)4096);
-    std::memcpy(&out[index], &reserved_size, sizeof(reserved_size));
+    std::memcpy(&out[index], &bd_info.reservedSize, sizeof(bd_info.reservedSize));
 
     return out;
   }
@@ -265,7 +263,11 @@
       {qtigralloc::MetadataType_FD, "fd from private_handle_t", true, false},
       {qtigralloc::MetadataType_PrivateFlags, "Flags in private_handle_t", true, false},
       {qtigralloc::MetadataType_AlignedWidthInPixels, "width in private_handle_t", true, false},
-      {qtigralloc::MetadataType_AlignedHeightInPixels, "height in private_handle_t", true, false}
+      {qtigralloc::MetadataType_AlignedHeightInPixels, "height in private_handle_t", true, false},
+#ifdef METADATA_V2
+      {qtigralloc::MetadataType_StandardMetadataStatus, "Is standard metadata set", true, false},
+      {qtigralloc::MetadataType_VendorMetadataStatus, "Is vendor metadata set", true, false}
+#endif
   };
 };
 
diff --git a/gralloc/gr_buf_mgr.cpp b/gralloc/gr_buf_mgr.cpp
index b44f1e9..fb1282a 100644
--- a/gralloc/gr_buf_mgr.cpp
+++ b/gralloc/gr_buf_mgr.cpp
@@ -52,17 +52,28 @@
 using aidl::android::hardware::graphics::common::StandardMetadataType;
 using aidl::android::hardware::graphics::common::XyColor;
 using ::android::hardware::graphics::common::V1_2::PixelFormat;
+
 static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
   return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
                     descriptor.GetUsage());
 }
 
-// duplicate from qdmetadata
-static uint64_t getMetaDataSize() {
-  return static_cast<uint64_t>(ROUND_UP_PAGESIZE(sizeof(MetaData_t)));
+static uint64_t getMetaDataSize(uint64_t reserved_region_size) {
+// Only include the reserved region size when using Metadata_t V2
+#ifndef METADATA_V2
+  reserved_region_size = 0;
+#endif
+  return static_cast<uint64_t>(ROUND_UP_PAGESIZE(sizeof(MetaData_t) + reserved_region_size));
 }
 
-static int validateAndMap(private_handle_t *handle) {
+static void unmapAndReset(private_handle_t *handle, uint64_t reserved_region_size = 0) {
+  if (private_handle_t::validate(handle) == 0 && handle->base_metadata) {
+    munmap(reinterpret_cast<void *>(handle->base_metadata), getMetaDataSize(reserved_region_size));
+    handle->base_metadata = 0;
+  }
+}
+
+static int validateAndMap(private_handle_t *handle, uint64_t reserved_region_size = 0) {
   if (private_handle_t::validate(handle)) {
     ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
     return -1;
@@ -73,26 +84,36 @@
   }
 
   if (!handle->base_metadata) {
-    auto size = getMetaDataSize();
+    uint64_t size = getMetaDataSize(reserved_region_size);
     void *base = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd_metadata, 0);
     if (base == reinterpret_cast<void *>(MAP_FAILED)) {
       ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s", __func__, handle,
             handle->fd_metadata, strerror(errno));
-
       return -1;
     }
     handle->base_metadata = (uintptr_t)base;
+#ifdef METADATA_V2
+    // The allocator process gets the reserved region size from the BufferDescriptor.
+    // When importing to another process, the reserved size is unknown until mapping the metadata,
+    // hence the re-mapping below
+    auto metadata = reinterpret_cast<MetaData_t*>(handle->base_metadata);
+    if (reserved_region_size == 0 && metadata->reservedSize) {
+        size = getMetaDataSize(metadata->reservedSize);
+        unmapAndReset(handle);
+        void *new_base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
+                              handle->fd_metadata, 0);
+        if (new_base == reinterpret_cast<void*>(MAP_FAILED)) {
+          ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s",
+                __func__, handle, handle->fd_metadata, strerror(errno));
+          return -1;
+        }
+        handle->base_metadata = (uintptr_t)new_base;
+    }
+#endif
   }
   return 0;
 }
 
-static void unmapAndReset(private_handle_t *handle) {
-  if (private_handle_t::validate(handle) == 0 && handle->base_metadata) {
-    munmap(reinterpret_cast<void *>(handle->base_metadata), getMetaDataSize());
-    handle->base_metadata = 0;
-  }
-}
-
 static Error dataspaceToColorMetadata(Dataspace dataspace, ColorMetaData *color_metadata) {
   ColorMetaData out;
   uint32_t primaries = (uint32_t)dataspace & (uint32_t)Dataspace::STANDARD_MASK;
@@ -709,7 +730,8 @@
     return Error::BAD_BUFFER;
   }
 
-  unsigned int meta_size = getMetaDataSize();
+  auto meta_size = getMetaDataSize(buf->reserved_size);
+
   if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
                              hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
     return Error::BAD_BUFFER;
@@ -741,6 +763,23 @@
 void BufferManager::RegisterHandleLocked(const private_handle_t *hnd, int ion_handle,
                                          int ion_handle_meta) {
   auto buffer = std::make_shared<Buffer>(hnd, ion_handle, ion_handle_meta);
+
+  if (hnd->base_metadata) {
+    auto metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
+#ifdef METADATA_V2
+    buffer->reserved_size = metadata->reservedSize;
+    if (buffer->reserved_size > 0) {
+      buffer->reserved_region_ptr =
+          reinterpret_cast<void *>(hnd->base_metadata + sizeof(MetaData_t));
+    } else {
+      buffer->reserved_region_ptr = nullptr;
+    }
+#else
+    buffer->reserved_region_ptr = reinterpret_cast<void *>(&(metadata->reservedRegion.data));
+    buffer->reserved_size = metadata->reservedRegion.size;
+#endif
+  }
+
   handles_map_.emplace(std::make_pair(hnd, buffer));
 }
 
@@ -768,6 +807,12 @@
   hnd->base = 0;
   hnd->base_metadata = 0;
   hnd->gpuaddr = 0;
+
+  if (validateAndMap(hnd)) {
+    ALOGE("Failed to map metadata: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id);
+    return Error::BAD_BUFFER;
+  }
+
   RegisterHandleLocked(hnd, ion_handle, ion_handle_meta);
   return Error::NONE;
 }
@@ -986,7 +1031,7 @@
 
   // Allocate memory for MetaData
   AllocData e_data;
-  e_data.size = getMetaDataSize();
+  e_data.size = static_cast<unsigned int>(getMetaDataSize(descriptor.GetReservedSize()));
   e_data.handle = data.handle;
   e_data.align = page_size;
 
@@ -1019,7 +1064,12 @@
     setMetaDataAndUnmap(hnd, SET_GRAPHICS_METADATA, reinterpret_cast<void *>(&graphics_metadata));
   }
 
+#ifdef METADATA_V2
+  auto error = validateAndMap(hnd, descriptor.GetReservedSize());
+#else
   auto error = validateAndMap(hnd);
+#endif
+
   if (error != 0) {
     ALOGE("validateAndMap failed");
     return Error::BAD_BUFFER;
@@ -1029,14 +1079,18 @@
   nameLength = descriptor.GetName().copy(metadata->name, nameLength);
   metadata->name[nameLength] = '\0';
 
-  metadata->reservedRegion.size = descriptor.GetReservedSize();
-
+#ifdef METADATA_V2
+  metadata->reservedSize = descriptor.GetReservedSize();
+#else
+  metadata->reservedRegion.size =
+      std::min(descriptor.GetReservedSize(), (uint64_t)RESERVED_REGION_SIZE);
+#endif
   metadata->crop.top = 0;
   metadata->crop.left = 0;
   metadata->crop.right = hnd->width;
   metadata->crop.bottom = hnd->height;
 
-  unmapAndReset(hnd);
+  unmapAndReset(hnd, descriptor.GetReservedSize());
 
   *handle = hnd;
 
@@ -1095,14 +1149,12 @@
   auto buf = GetBufferFromHandleLocked(handle);
   if (buf == nullptr)
     return Error::BAD_BUFFER;
-
-  auto err = validateAndMap(handle);
-  if (err != 0)
+  if (!handle->base_metadata) {
     return Error::BAD_BUFFER;
-  auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
+  }
 
-  *reserved_region = reinterpret_cast<void *>(&(metadata->reservedRegion.data));
-  *reserved_region_size = metadata->reservedRegion.size;
+  *reserved_region = buf->reserved_region_ptr;
+  *reserved_region_size = buf->reserved_size;
 
   return Error::NONE;
 }
@@ -1116,9 +1168,9 @@
   if (buf == nullptr)
     return Error::BAD_BUFFER;
 
-  auto err = validateAndMap(handle);
-  if (err != 0)
+  if (!handle->base_metadata) {
     return Error::BAD_BUFFER;
+  }
 
   auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
 
@@ -1175,9 +1227,17 @@
       android::gralloc4::encodeChromaSiting(android::gralloc4::ChromaSiting_None, out);
       break;
     case (int64_t)StandardMetadataType::DATASPACE:
-      Dataspace dataspace;
-      colorMetadataToDataspace(metadata->color, &dataspace);
-      android::gralloc4::encodeDataspace(dataspace, out);
+#ifdef METADATA_V2
+      if (metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)]) {
+#endif
+        Dataspace dataspace;
+        colorMetadataToDataspace(metadata->color, &dataspace);
+        android::gralloc4::encodeDataspace(dataspace, out);
+#ifdef METADATA_V2
+      } else {
+        android::gralloc4::encodeDataspace(Dataspace::UNKNOWN, out);
+      }
+#endif
       break;
     case (int64_t)StandardMetadataType::INTERLACED:
       if (metadata->interlaced > 0) {
@@ -1328,6 +1388,14 @@
       android::gralloc4::encodeUint32(qtigralloc::MetadataType_AlignedHeightInPixels,
                                       handle->height, out);
       break;
+#ifdef METADATA_V2
+    case QTI_STANDARD_METADATA_STATUS:
+      qtigralloc::encodeMetadataState(metadata->isStandardMetadataSet, out);
+      break;
+    case QTI_VENDOR_METADATA_STATUS:
+      qtigralloc::encodeMetadataState(metadata->isVendorMetadataSet, out);
+      break;
+#endif
     default:
       error = Error::UNSUPPORTED;
   }
@@ -1345,9 +1413,12 @@
   if (buf == nullptr)
     return Error::BAD_BUFFER;
 
-  int err = validateAndMap(handle);
-  if (err != 0)
+  if (!handle->base_metadata) {
     return Error::BAD_BUFFER;
+  }
+  if (in.size() == 0) {
+    return Error::UNSUPPORTED;
+  }
 
   if (in.size() == 0) {
     return Error::UNSUPPORTED;
@@ -1355,6 +1426,16 @@
 
   auto metadata = reinterpret_cast<MetaData_t *>(handle->base_metadata);
 
+#ifdef METADATA_V2
+  // By default, set these to true
+  // Reset to false for special cases below
+  if (IS_VENDOR_METADATA_TYPE(metadatatype_value)) {
+    metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(metadatatype_value)] = true;
+  } else {
+    metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)] = true;
+  }
+#endif
+
   switch (metadatatype_value) {
     // These are constant (unchanged after allocation)
     case (int64_t)StandardMetadataType::BUFFER_ID:
@@ -1419,6 +1500,10 @@
         metadata->color.masteringDisplayInfo.minDisplayLuminance =
             static_cast<uint32_t>(mastering_display_values->minLuminance * 10000.0f);
       } else {
+#ifdef METADATA_V2
+        metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)] =
+            false;
+#endif
         metadata->color.masteringDisplayInfo.colorVolumeSEIEnabled = false;
       }
       break;
@@ -1433,6 +1518,10 @@
         metadata->color.contentLightLevel.minPicAverageLightLevel =
             static_cast<uint32_t>(content_light_level->maxFrameAverageLightLevel * 10000.0f);
       } else {
+#ifdef METADATA_V2
+        metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)] =
+            false;
+#endif
         metadata->color.contentLightLevel.lightLevelSEIEnabled = false;
       }
       break;
@@ -1451,6 +1540,10 @@
         metadata->color.dynamicMetaDataValid = true;
       } else {
         // Reset metadata by passing in std::nullopt
+#ifdef METADATA_V2
+        metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)] =
+            false;
+#endif
         metadata->color.dynamicMetaDataValid = false;
       }
       break;
@@ -1513,8 +1606,17 @@
       qtigralloc::decodeVideoHistogramMetadata(in, &metadata->video_histogram_stats);
       break;
     default:
+#ifdef METADATA_V2
+      if (IS_VENDOR_METADATA_TYPE(metadatatype_value)) {
+        metadata->isVendorMetadataSet[GET_VENDOR_METADATA_STATUS_INDEX(metadatatype_value)] = false;
+      } else {
+        metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)] =
+            false;
+      }
+#endif
       return Error::BAD_VALUE;
   }
+
   return Error::NONE;
 }
 
diff --git a/gralloc/gr_buf_mgr.h b/gralloc/gr_buf_mgr.h
index 2295799..6c5dc83 100644
--- a/gralloc/gr_buf_mgr.h
+++ b/gralloc/gr_buf_mgr.h
@@ -88,6 +88,8 @@
         : handle(h), ion_handle_main(ih_main), ion_handle_meta(ih_meta) {}
     void IncRef() { ++ref_count; }
     bool DecRef() { return --ref_count == 0; }
+    uint64_t reserved_size = 0;
+    void *reserved_region_ptr = nullptr;
   };
 
   Error FreeBuffer(std::shared_ptr<Buffer> buf);