/*
 * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
 *
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of The Linux Foundation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
#include <log/log.h>
#include <cutils/trace.h>
#include <sync/sync.h>
#include <utils/Trace.h>
#include <algorithm>
#include <sstream>
#include <string>

#include "gr_buf_descriptor.h"
#include "gr_device_impl.h"
#include "gr_utils.h"
#include <QtiGrallocPriv.h>
#include <QtiGrallocDefs.h>
#include "qd_utils.h"

int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device);

int gralloc_device_close(struct hw_device_t *device);

static struct hw_module_methods_t gralloc_module_methods = {.open = gralloc_device_open};

struct gralloc_module_t HAL_MODULE_INFO_SYM = {
    // clang-format off
    .common = {
            .tag = HARDWARE_MODULE_TAG,
            .module_api_version = GRALLOC_MODULE_API_VERSION_1_0,
            .hal_api_version = HARDWARE_HAL_API_VERSION,
            .id = GRALLOC_HARDWARE_MODULE_ID,
            .name = "Graphics Memory Module",
            .author = "Code Aurora Forum",
            .methods = &gralloc_module_methods,
            .dso = 0,
            .reserved = {0},
        },
    // clang-format on
};

int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device) {
  int status = -EINVAL;
  if (module && device && !strcmp(name, GRALLOC_HARDWARE_MODULE_ID)) {
    gralloc::GrallocImpl * /*gralloc1_device_t*/ dev = gralloc::GrallocImpl::GetInstance(module);
    *device = reinterpret_cast<hw_device_t *>(dev);
    if (dev) {
      status = 0;
    } else {
      ALOGE("Fatal error opening gralloc1 device");
    }
  }
  return status;
}

namespace gralloc {

std::atomic<uint64_t> GrallocImpl::next_descriptor_id_(1);

GrallocImpl::GrallocImpl(const hw_module_t *module) {
  common.tag = HARDWARE_DEVICE_TAG;
  common.version = GRALLOC_MODULE_API_VERSION_1_0;
  common.module = const_cast<hw_module_t *>(module);
  common.close = CloseDevice;
  getFunction = GetFunction;
  getCapabilities = GetCapabilities;

  initialized_ = Init();
}

inline gralloc1_error_t ToError(Error error) {
  switch (error) {
    case Error::NONE:
      return GRALLOC1_ERROR_NONE;
    case Error::BAD_DESCRIPTOR:
      return GRALLOC1_ERROR_BAD_DESCRIPTOR;
    case Error::BAD_BUFFER:
      return GRALLOC1_ERROR_BAD_HANDLE;
    case Error::BAD_VALUE:
      return GRALLOC1_ERROR_BAD_VALUE;
    case Error::NO_RESOURCES:
      return GRALLOC1_ERROR_NO_RESOURCES;
    case Error::UNSUPPORTED:
    default:
      return GRALLOC1_ERROR_UNSUPPORTED;
  }
}

static uint64_t ProducerUsageToBufferUsage(uint64_t /*gralloc1_producer_usage_t*/ producer_usage) {
  uint64_t usage =
      producer_usage &
      ~(GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN | GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN);
  if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) ==
      GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) {
    usage |= BufferUsage::CPU_READ_OFTEN;
  } else if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) ==
             GRALLOC1_PRODUCER_USAGE_CPU_READ) {
    usage |= BufferUsage::CPU_READ_RARELY;
  }

  if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) ==
      GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) {
    usage |= BufferUsage::CPU_WRITE_OFTEN;
  } else if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) ==
             GRALLOC1_PRODUCER_USAGE_CPU_WRITE) {
    usage |= BufferUsage::CPU_WRITE_RARELY;
  }
  return usage;
}

static uint64_t ConsumerUsageToBufferUsage(uint64_t /*gralloc1_consumer_usage_t*/ consumer_usage) {
  uint64_t usage = consumer_usage & ~(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN);
  if ((consumer_usage & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) ==
      GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) {
    usage |= BufferUsage::CPU_READ_OFTEN;
  } else if ((consumer_usage & GRALLOC1_CONSUMER_USAGE_CPU_READ) ==
             GRALLOC1_CONSUMER_USAGE_CPU_READ) {
    usage |= BufferUsage::CPU_READ_RARELY;
  }
  return usage;
}

bool GrallocImpl::Init() {
  buf_mgr_ = BufferManager::GetInstance();
  return buf_mgr_ != nullptr;
}

GrallocImpl::~GrallocImpl() {}

gralloc1_error_t GrallocImpl::CreateBufferDescriptorLocked(
    gralloc1_buffer_descriptor_t *descriptor_id) {
  std::lock_guard<std::mutex> lock(descriptor_lock_);
  auto descriptor = std::make_shared<BufferDescriptor>(next_descriptor_id_++);
  *descriptor_id = static_cast<gralloc1_buffer_descriptor_t>(descriptor->GetId());
  descriptors_map_.emplace(*descriptor_id, descriptor);
  return GRALLOC1_ERROR_NONE;
}

gralloc1_error_t GrallocImpl::DestroyBufferDescriptorLocked(
    gralloc1_buffer_descriptor_t descriptor_id) {
  std::lock_guard<std::mutex> lock(descriptor_lock_);
  const auto descriptor = descriptors_map_.find(descriptor_id);
  if (descriptor == descriptors_map_.end()) {
    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
  }
  descriptors_map_.erase(descriptor);
  return GRALLOC1_ERROR_NONE;
}

int GrallocImpl::CloseDevice(hw_device_t *device __unused) {
  // No-op since the gralloc device is a singleton
  return 0;
}

void GrallocImpl::GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
                                  int32_t /*gralloc1_capability_t*/ *out_capabilities) {
  if (device != nullptr && out_count != nullptr) {
    if (out_capabilities != nullptr && *out_count >= 3) {
      out_capabilities[0] = GRALLOC1_CAPABILITY_TEST_ALLOCATE;
      out_capabilities[1] = GRALLOC1_CAPABILITY_LAYERED_BUFFERS;
      out_capabilities[2] = GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE;
    }
    *out_count = 3;
  }
  return;
}

gralloc1_function_pointer_t GrallocImpl::GetFunction(gralloc1_device_t *device, int32_t function) {
  if (!device) {
    return NULL;
  }

  switch (function) {
    case GRALLOC1_FUNCTION_DUMP:
      return reinterpret_cast<gralloc1_function_pointer_t>(Dump);
    case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
      return reinterpret_cast<gralloc1_function_pointer_t>(CreateBufferDescriptor);
    case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
      return reinterpret_cast<gralloc1_function_pointer_t>(DestroyBufferDescriptor);
    case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
      return reinterpret_cast<gralloc1_function_pointer_t>(SetConsumerUsage);
    case GRALLOC1_FUNCTION_SET_DIMENSIONS:
      return reinterpret_cast<gralloc1_function_pointer_t>(SetBufferDimensions);
    case GRALLOC1_FUNCTION_SET_FORMAT:
      return reinterpret_cast<gralloc1_function_pointer_t>(SetColorFormat);
    case GRALLOC1_FUNCTION_SET_LAYER_COUNT:
      return reinterpret_cast<gralloc1_function_pointer_t>(SetLayerCount);
    case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
      return reinterpret_cast<gralloc1_function_pointer_t>(SetProducerUsage);
    case GRALLOC1_FUNCTION_GET_BACKING_STORE:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetBackingStore);
    case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetConsumerUsage);
    case GRALLOC1_FUNCTION_GET_DIMENSIONS:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferDimensions);
    case GRALLOC1_FUNCTION_GET_FORMAT:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetColorFormat);
    case GRALLOC1_FUNCTION_GET_LAYER_COUNT:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetLayerCount);
    case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetProducerUsage);
    case GRALLOC1_FUNCTION_GET_STRIDE:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferStride);
    case GRALLOC1_FUNCTION_ALLOCATE:
      return reinterpret_cast<gralloc1_function_pointer_t>(AllocateBuffers);
    case GRALLOC1_FUNCTION_RETAIN:
      return reinterpret_cast<gralloc1_function_pointer_t>(RetainBuffer);
    case GRALLOC1_FUNCTION_RELEASE:
      return reinterpret_cast<gralloc1_function_pointer_t>(ReleaseBuffer);
    case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetNumFlexPlanes);
    case GRALLOC1_FUNCTION_LOCK:
      return reinterpret_cast<gralloc1_function_pointer_t>(LockBuffer);
    case GRALLOC1_FUNCTION_LOCK_FLEX:
      return reinterpret_cast<gralloc1_function_pointer_t>(LockFlex);
    case GRALLOC1_FUNCTION_UNLOCK:
      return reinterpret_cast<gralloc1_function_pointer_t>(UnlockBuffer);
    case GRALLOC1_FUNCTION_PERFORM:
      return reinterpret_cast<gralloc1_function_pointer_t>(Gralloc1Perform);
    default:
      ALOGE("%s:Gralloc Error. Client Requested for unsupported function", __FUNCTION__);
      return NULL;
  }

  return NULL;
}

void GrallocImpl::Dump(gralloc1_device_t *device, uint32_t *out_size, char *out_buffer) {
  if (!device || !out_size) {
    ALOGE("Gralloc Error : device=%p", (void *)device);
    return;
  }
  const size_t max_dump_size = 8192;
  if (out_buffer == nullptr) {
    *out_size = max_dump_size;
  } else {
    std::ostringstream os;
    os << "-------------------------------" << std::endl;
    os << "QTI gralloc dump:" << std::endl;
    os << "-------------------------------" << std::endl;
    GrallocImpl const *dev = GRALLOC_IMPL(device);
    dev->buf_mgr_->Dump(&os);
    os << "-------------------------------" << std::endl;
    auto copied = os.str().copy(out_buffer, std::min(os.str().size(), max_dump_size), 0);
    *out_size = UINT(copied);
  }

  return;
}

gralloc1_error_t GrallocImpl::CheckDeviceAndHandle(gralloc1_device_t *device,
                                                   buffer_handle_t buffer) {
  const private_handle_t *hnd = QTI_HANDLE_CONST(buffer);
  if (!device || (private_handle_t::validate(hnd) != 0)) {
    ALOGE("Gralloc Error : device= %p, buffer-handle=%p", (void *)device, (void *)buffer);
    return GRALLOC1_ERROR_BAD_HANDLE;
  }

  return GRALLOC1_ERROR_NONE;
}

int32_t GrallocImpl::CreateBufferDescriptor(gralloc1_device_t *device,
                                            gralloc1_buffer_descriptor_t *out_descriptor) {
  if (!device || !out_descriptor) {
    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
  }
  auto *dev = reinterpret_cast<GrallocImpl *>(device);
  return static_cast<int32_t>(dev->CreateBufferDescriptorLocked(out_descriptor));
}

int32_t GrallocImpl::DestroyBufferDescriptor(gralloc1_device_t *device,
                                             gralloc1_buffer_descriptor_t descriptor) {
  if (!device) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
  }
  auto *dev = reinterpret_cast<GrallocImpl *>(device);
  return static_cast<int32_t>(dev->DestroyBufferDescriptorLocked(descriptor));
}

int32_t GrallocImpl::SetConsumerUsage(gralloc1_device_t *device,
                                      gralloc1_buffer_descriptor_t descriptor,
                                      uint64_t /*gralloc1_consumer_usage_t*/ usage) {
  if (!device) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
  } else {
    auto *dev = reinterpret_cast<GrallocImpl *>(device);
    return static_cast<int32_t>(dev->CallBufferDescriptorFunction(
        descriptor, &BufferDescriptor::SetUsage, ConsumerUsageToBufferUsage(usage)));
  }
}

int32_t GrallocImpl::SetBufferDimensions(gralloc1_device_t *device,
                                         gralloc1_buffer_descriptor_t descriptor, uint32_t width,
                                         uint32_t height) {
  if (!device) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
  } else {
    auto *dev = reinterpret_cast<GrallocImpl *>(device);
    return static_cast<int32_t>(dev->CallBufferDescriptorFunction(
        descriptor, &BufferDescriptor::SetDimensions, INT(width), INT(height)));
  }
}

int32_t GrallocImpl::SetColorFormat(gralloc1_device_t *device,
                                    gralloc1_buffer_descriptor_t descriptor, int32_t format) {
  if (!device) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
  } else {
    auto *dev = reinterpret_cast<GrallocImpl *>(device);
    return static_cast<int32_t>(
        dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetColorFormat, format));
  }
}

int32_t GrallocImpl::SetLayerCount(gralloc1_device_t *device,
                                   gralloc1_buffer_descriptor_t descriptor, uint32_t layer_count) {
  if (!device) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
  } else {
    auto *dev = reinterpret_cast<GrallocImpl *>(device);
    return static_cast<int32_t>(dev->CallBufferDescriptorFunction(
        descriptor, &BufferDescriptor::SetLayerCount, layer_count));
  }
}

int32_t GrallocImpl::SetProducerUsage(gralloc1_device_t *device,
                                      gralloc1_buffer_descriptor_t descriptor,
                                      uint64_t /*gralloc1_producer_usage_t*/ usage) {
  if (!device) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
  } else {
    auto *dev = reinterpret_cast<GrallocImpl *>(device);
    return static_cast<int32_t>(dev->CallBufferDescriptorFunction(
        descriptor, &BufferDescriptor::SetUsage, ProducerUsageToBufferUsage(usage)));
  }
}

int32_t GrallocImpl::GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer,
                                     gralloc1_backing_store_t *out_backstore) {
  if (!out_backstore) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
  }

  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    *out_backstore =
        static_cast<gralloc1_backing_store_t>(QTI_HANDLE_CONST(buffer)->GetBackingstore());
  }

  return status;
}

int32_t GrallocImpl::GetConsumerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
                                      uint64_t /*gralloc1_consumer_usage_t*/ *outUsage) {
  if (!outUsage) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
  }

  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    *outUsage = static_cast<uint64_t>(QTI_HANDLE_CONST(buffer)->GetUsage());
  }

  return static_cast<int32_t>(status);
}

int32_t GrallocImpl::GetBufferDimensions(gralloc1_device_t *device, buffer_handle_t buffer,
                                         uint32_t *outWidth, uint32_t *outHeight) {
  if (!outWidth || !outHeight) {
    return GRALLOC1_ERROR_BAD_VALUE;
  }

  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    const private_handle_t *hnd = QTI_HANDLE_CONST(buffer);
    *outWidth = UINT(hnd->GetUnalignedWidth());
    *outHeight = UINT(hnd->GetUnalignedHeight());
  }

  return static_cast<int32_t>(status);
}

int32_t GrallocImpl::GetColorFormat(gralloc1_device_t *device, buffer_handle_t buffer,
                                    int32_t *outFormat) {
  if (!outFormat) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
  }

  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    *outFormat = QTI_HANDLE_CONST(buffer)->GetColorFormat();
  }

  return static_cast<int32_t>(status);
}

int32_t GrallocImpl::GetLayerCount(gralloc1_device_t *device, buffer_handle_t buffer,
                                   uint32_t *outLayerCount) {
  if (!outLayerCount) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
  }

  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    *outLayerCount = QTI_HANDLE_CONST(buffer)->GetLayerCount();
  }

  return static_cast<int32_t>(status);
}

int32_t GrallocImpl::GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
                                      uint64_t /*gralloc1_producer_usage_t*/ *outUsage) {
  if (!outUsage) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
  }

  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    *outUsage = static_cast<uint64_t>(QTI_HANDLE_CONST(buffer)->GetUsage());
  }

  return static_cast<int32_t>(status);
}

int32_t GrallocImpl::GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
                                     uint32_t *outStride) {
  if (!outStride) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
  }

  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    *outStride = UINT(QTI_HANDLE_CONST(buffer)->GetStride());
  }

  return static_cast<int32_t>(status);
}

gralloc1_error_t GrallocImpl::AllocateBuffer(const gralloc1_buffer_descriptor_t *descriptor_ids,
                                             buffer_handle_t *out_buffers) {
  gralloc1_error_t status = GRALLOC1_ERROR_NONE;

  // Validate descriptor
  std::lock_guard<std::mutex> descriptor_lock(descriptor_lock_);
  std::shared_ptr<gralloc::BufferDescriptor> descriptor;
  const auto map_descriptor = descriptors_map_.find(descriptor_ids[0]);
  if (map_descriptor == descriptors_map_.end()) {
    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
  } else {
    descriptor = map_descriptor->second;
  }

  // Allocate separate buffer for each descriptor
  if (buf_mgr_->AllocateBuffer(*descriptor, &out_buffers[0]) != Error::NONE) {
    return GRALLOC1_ERROR_NO_RESOURCES;
  }

  return status;
}

int32_t GrallocImpl::AllocateBuffers(gralloc1_device_t *device, uint32_t num_descriptors,
                                     const gralloc1_buffer_descriptor_t *descriptors,
                                     buffer_handle_t *out_buffers) {
  if (!num_descriptors || !descriptors) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
  }

  if (!device) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
  }

  if (num_descriptors != 1) {
    return static_cast<int32_t>(GRALLOC1_ERROR_UNSUPPORTED);
  }

  auto *dev = reinterpret_cast<GrallocImpl *>(device);
  gralloc1_error_t status = dev->AllocateBuffer(descriptors, out_buffers);

  return static_cast<int32_t>(status);
}

int32_t GrallocImpl::RetainBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    const private_handle_t *hnd = QTI_HANDLE_CONST(buffer);
    GrallocImpl const *dev = GRALLOC_IMPL(device);
    status = ToError(dev->buf_mgr_->RetainBuffer(hnd));
  }

  return static_cast<int32_t>(status);
}

int32_t GrallocImpl::ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
  if (!device || !buffer) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
  }

  const private_handle_t *hnd = QTI_HANDLE_CONST(buffer);
  GrallocImpl const *dev = GRALLOC_IMPL(device);
  return static_cast<int32_t>((ToError(dev->buf_mgr_->ReleaseBuffer(hnd))));
}

int32_t GrallocImpl::GetFlexLayout(const private_handle_t *hnd,
                                   struct android_flex_layout *layout) {
  if (!IsYuvFormat(hnd->format)) {
    return static_cast<int32_t>(GRALLOC1_ERROR_UNSUPPORTED);
  }

  android_ycbcr yuvPlaneInfo[2];
  int err = GetYUVPlaneInfo(hnd, yuvPlaneInfo);

  if (err != 0) {
    return GRALLOC1_ERROR_BAD_HANDLE;
  }

  layout->format = FLEX_FORMAT_YCbCr;
  layout->num_planes = 3;

  for (uint32_t i = 0; i < layout->num_planes; i++) {
    layout->planes[i].bits_per_component = 8;
    layout->planes[i].bits_used = 8;
    layout->planes[i].h_increment = 1;
    layout->planes[i].v_increment = 1;
    layout->planes[i].h_subsampling = 2;
    layout->planes[i].v_subsampling = 2;
  }

  // We are only returning flex layout for progressive or single field formats.
  struct android_ycbcr ycbcr = yuvPlaneInfo[0];
  layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
  layout->planes[0].component = FLEX_COMPONENT_Y;
  layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);

  layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
  layout->planes[1].component = FLEX_COMPONENT_Cb;
  layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
  layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);

  layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
  layout->planes[2].component = FLEX_COMPONENT_Cr;
  layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
  layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
  return static_cast<int32_t>(GRALLOC1_ERROR_NONE);
}

int32_t GrallocImpl::GetNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer,
                                      uint32_t *out_num_planes) {
  if (!out_num_planes) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
  }

  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    const private_handle_t *hnd = QTI_HANDLE_CONST(buffer);
    if (!IsYuvFormat(hnd->format)) {
      status = GRALLOC1_ERROR_UNSUPPORTED;
    } else {
      *out_num_planes = 3;
    }
  }
  return static_cast<int32_t>(status);
}

static inline void CloseFdIfValid(int fd) {
  if (fd > 0) {
    close(fd);
  }
}

int32_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
                                uint64_t /*gralloc1_producer_usage_t*/ prod_usage,
                                uint64_t /*gralloc1_consumer_usage_t*/ cons_usage,
                                const gralloc1_rect_t *region, void **out_data,
                                int32_t acquire_fence) {
  ATRACE_CALL();
  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status != GRALLOC1_ERROR_NONE || !out_data ||
      !region) {  // currently we ignore the region/rect client wants to lock
    CloseFdIfValid(acquire_fence);
    return static_cast<int32_t>(status);
  }

  if (acquire_fence > 0) {
    ATRACE_BEGIN("fence wait");
    int error = sync_wait(acquire_fence, 1000);
    ATRACE_END();
    CloseFdIfValid(acquire_fence);
    if (error < 0) {
      ALOGE("%s: sync_wait timedout! error = %s", __FUNCTION__, strerror(errno));
      return static_cast<int32_t>(GRALLOC1_ERROR_UNDEFINED);
    }
  }

  const private_handle_t *hnd = QTI_HANDLE_CONST(buffer);
  GrallocImpl const *dev = GRALLOC_IMPL(device);

  // Either producer usage or consumer usage must be *_USAGE_NONE
  if ((prod_usage != GRALLOC1_PRODUCER_USAGE_NONE) &&
      (cons_usage != GRALLOC1_CONSUMER_USAGE_NONE)) {
    // Current gralloc1 clients do not satisfy this restriction.
    // See b/33588773 for details
    // return GRALLOC1_ERROR_BAD_VALUE;
  }

  status = ToError(dev->buf_mgr_->LockBuffer(
      hnd, ProducerUsageToBufferUsage(prod_usage) | ConsumerUsageToBufferUsage(cons_usage)));
  *out_data = reinterpret_cast<void *>(hnd->base);

  return static_cast<int32_t>(status);
}

int32_t GrallocImpl::LockFlex(gralloc1_device_t *device, buffer_handle_t buffer,
                              uint64_t /*gralloc1_producer_usage_t*/ prod_usage,
                              uint64_t /*gralloc1_consumer_usage_t*/ cons_usage,
                              const gralloc1_rect_t *region,
                              struct android_flex_layout *out_flex_layout, int32_t acquire_fence) {
  if (!out_flex_layout) {
    CloseFdIfValid(acquire_fence);
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
  }

  void *out_data{};
  int32_t status = GrallocImpl::LockBuffer(device, buffer, prod_usage, cons_usage, region,
                                           &out_data, acquire_fence);
  if (status != GRALLOC1_ERROR_NONE) {
    return static_cast<int32_t>(status);
  }

  auto *dev = reinterpret_cast<GrallocImpl *>(device);
  const private_handle_t *hnd = QTI_HANDLE_CONST(buffer);
  dev->GetFlexLayout(hnd, out_flex_layout);
  return static_cast<int32_t>(status);
}

int32_t GrallocImpl::UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
                                  int32_t *release_fence) {
  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status != GRALLOC1_ERROR_NONE) {
    return static_cast<int32_t>(status);
  }

  if (!release_fence) {
    return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
  }

  const private_handle_t *hnd = QTI_HANDLE_CONST(buffer);
  GrallocImpl const *dev = GRALLOC_IMPL(device);

  *release_fence = -1;

  return static_cast<int32_t>(ToError(dev->buf_mgr_->UnlockBuffer(hnd)));
}

static int32_t Perform(int operation, va_list args) {
  switch (operation) {
    case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
      int width = va_arg(args, int);
      int format = va_arg(args, int);
      int *stride = va_arg(args, int *);
      unsigned int alignedw = 0, alignedh = 0;

      if (!stride) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }

      BufferInfo info(width, width, format);
      int err = GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
      if (err) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }
      *stride = INT(alignedw);
    } break;

    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
      private_handle_t *hnd = va_arg(args, private_handle_t *);
      int *stride = va_arg(args, int *);
      if (private_handle_t::validate(hnd) != 0) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
      }

      if (!stride) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }

      BufferDim_t buffer_dim;
      if (getMetaDataValue(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == Error::NONE) {
        *stride = buffer_dim.sliceWidth;
      } else {
        *stride = hnd->width;
      }
    } break;

    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
      private_handle_t *hnd = va_arg(args, private_handle_t *);
      int *stride = va_arg(args, int *);
      int *height = va_arg(args, int *);
      if (private_handle_t::validate(hnd) != 0) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
      }

      if (!stride || !height) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }

      int err = GetCustomDimensions(hnd, stride, height);
      if (err) {
        ALOGW(
            "%s: Error during GetCustomDimensions API Call. "
            "stride: %d, height: %d",
            __FUNCTION__, *stride, *height);
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }
    } break;

    case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
      int width = va_arg(args, int);
      int height = va_arg(args, int);
      int format = va_arg(args, int);
      uint64_t usage = va_arg(args, uint64_t);
      usage |= va_arg(args, uint64_t);

      int *aligned_width = va_arg(args, int *);
      int *aligned_height = va_arg(args, int *);
      int *tile_enabled = va_arg(args, int *);
      if (!aligned_width || !aligned_height || !tile_enabled) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }

      unsigned int alignedw, alignedh;
      BufferInfo info(width, height, format, usage);
      *tile_enabled = IsUBwcEnabled(format, usage);
      int err = GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
      if (err) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }
      *aligned_width = INT(alignedw);
      *aligned_height = INT(alignedh);
    } break;

    case GRALLOC_MODULE_PERFORM_QTI_COLORSPACE_FROM_HANDLE: {
      private_handle_t *hnd = va_arg(args, private_handle_t *);
      int *color_space = va_arg(args, int *);

      if (private_handle_t::validate(hnd) != 0) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
      }

      if (!color_space) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }

      *color_space = 0;
      GetColorSpaceFromMetadata(hnd, color_space);
    } break;
    case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
      private_handle_t *hnd = va_arg(args, private_handle_t *);
      android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
      if (private_handle_t::validate(hnd) != 0) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
      }

      if (!ycbcr) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }

      if (GetYUVPlaneInfo(hnd, ycbcr)) {
        return static_cast<int32_t>(GRALLOC1_ERROR_UNDEFINED);
      }
    } break;

    case GRALLOC_MODULE_PERFORM_QTI_MAP_SECURE_BUFFER_INFO: {
      private_handle_t *hnd = va_arg(args, private_handle_t *);
      int *map_secure_buffer = va_arg(args, int *);

      if (private_handle_t::validate(hnd) != 0) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
      }

      if (!map_secure_buffer) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }

      if (getMetaDataValue(hnd, QTI_MAP_SECURE_BUFFER, map_secure_buffer) != Error::NONE) {
        *map_secure_buffer = 0;
      }
    } break;

    case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
      private_handle_t *hnd = va_arg(args, private_handle_t *);
      int *flag = va_arg(args, int *);

      if (private_handle_t::validate(hnd) != 0) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
      }

      if (!flag) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }

      *flag = hnd->flags & qtigralloc::PRIV_FLAGS_UBWC_ALIGNED;
      int linear_format = 0;
      if (getMetaDataValue(hnd, QTI_LINEAR_FORMAT, &linear_format) == Error::NONE) {
        if (linear_format) {
          *flag = 0;
        }
      }
    } break;

    case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
      private_handle_t *hnd = va_arg(args, private_handle_t *);
      void **rgb_data = va_arg(args, void **);

      if (private_handle_t::validate(hnd) != 0) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
      }

      if (!rgb_data) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }

      if (GetRgbDataAddress(hnd, rgb_data)) {
        return static_cast<int32_t>(GRALLOC1_ERROR_UNDEFINED);
      }
    } break;

    case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
      private_handle_t *hnd = va_arg(args, private_handle_t *);
      int *flag = va_arg(args, int *);

      if (private_handle_t::validate(hnd) != 0) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
      }

      if (!flag) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
      }

      if (getMetaDataValue(hnd, QTI_PP_PARAM_INTERLACED, flag) != Error::NONE) {
        *flag = 0;
      }
    } break;

    case GRALLOC_MODULE_PERFORM_QTI_SINGLE_BUFFER_MODE: {
      private_handle_t *hnd = va_arg(args, private_handle_t *);
      uint32_t *enable = va_arg(args, uint32_t *);
      if (private_handle_t::validate(hnd) != 0) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
      }
      if (SetMetaData(hnd, QTI_SINGLE_BUFFER_MODE, enable) != Error::NONE) {
        return static_cast<int32_t>(GRALLOC1_ERROR_UNSUPPORTED);
      }
    } break;

    case GRALLOC_MODULE_PERFORM_QTI_GRAPHICS_METADATA: {
      private_handle_t *hnd = va_arg(args, private_handle_t *);

      if (private_handle_t::validate(hnd) != 0) {
        return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
      }

      void *graphic_metadata = va_arg(args, void *);

      if (getMetaDataValue(hnd, QTI_GRAPHICS_METADATA, graphic_metadata) != Error::NONE) {
        graphic_metadata = NULL;
        return static_cast<int32_t>(GRALLOC1_ERROR_UNSUPPORTED);
      }
    } break;

    default:
      break;
  }
  return static_cast<int32_t>(GRALLOC1_ERROR_NONE);
}

int32_t GrallocImpl::Gralloc1Perform(gralloc1_device_t *device, int operation, ...) {
  if (!device) {
    return GRALLOC1_ERROR_BAD_VALUE;
  }

  va_list args;
  va_start(args, operation);
  int32_t err = Perform(operation, args);
  va_end(args);

  return err;
}

}  // namespace gralloc
