/*
 * Copyright (c) 2016-2018, The Linux Foundation. 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 "gralloc_priv.h"
#include "qdMetaData.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(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(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;
}

gralloc1_error_t 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 GRALLOC1_ERROR_BAD_DESCRIPTOR;
  }
  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_NONE;
}

gralloc1_error_t GrallocImpl::CheckDeviceAndHandle(gralloc1_device_t *device,
                                                   buffer_handle_t buffer) {
  const private_handle_t *hnd = PRIV_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;
}

gralloc1_error_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 dev->CreateBufferDescriptorLocked(out_descriptor);
}

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

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

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

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

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

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

gralloc1_error_t GrallocImpl::GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer,
                                              gralloc1_backing_store_t *out_backstore) {
  if (!device || !buffer) {
    return GRALLOC1_ERROR_BAD_HANDLE;
  }

  *out_backstore =
      static_cast<gralloc1_backing_store_t>(PRIV_HANDLE_CONST(buffer)->GetBackingstore());

  return GRALLOC1_ERROR_NONE;
}

gralloc1_error_t GrallocImpl::GetConsumerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
                                               gralloc1_consumer_usage_t *outUsage) {
  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    *outUsage = static_cast<gralloc1_consumer_usage_t>(PRIV_HANDLE_CONST(buffer)->GetUsage());
  }

  return status;
}

gralloc1_error_t GrallocImpl::GetBufferDimensions(gralloc1_device_t *device, buffer_handle_t buffer,
                                                  uint32_t *outWidth, uint32_t *outHeight) {
  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
    *outWidth = UINT(hnd->GetUnalignedWidth());
    *outHeight = UINT(hnd->GetUnalignedHeight());
  }

  return status;
}

gralloc1_error_t GrallocImpl::GetColorFormat(gralloc1_device_t *device, buffer_handle_t buffer,
                                             int32_t *outFormat) {
  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    *outFormat = PRIV_HANDLE_CONST(buffer)->GetColorFormat();
  }

  return status;
}

gralloc1_error_t GrallocImpl::GetLayerCount(gralloc1_device_t *device, buffer_handle_t buffer,
                                            uint32_t *outLayerCount) {
  gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
  if (status == GRALLOC1_ERROR_NONE) {
    *outLayerCount = PRIV_HANDLE_CONST(buffer)->GetLayerCount();
  }

  return status;
}

gralloc1_error_t GrallocImpl::GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
                                               gralloc1_producer_usage_t *outUsage) {
  if (!outUsage) {
    return GRALLOC1_ERROR_BAD_VALUE;
  }

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

  return status;
}

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

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

  return 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;
}

gralloc1_error_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 GRALLOC1_ERROR_BAD_DESCRIPTOR;
  }

  if (!device) {
    return GRALLOC1_ERROR_BAD_VALUE;
  }

  if (num_descriptors != 1) {
    return GRALLOC1_ERROR_UNSUPPORTED;
  }

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

  return status;
}

gralloc1_error_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 = PRIV_HANDLE_CONST(buffer);
    GrallocImpl const *dev = GRALLOC_IMPL(device);
    status = ToError(dev->buf_mgr_->RetainBuffer(hnd));
  }

  return status;
}

gralloc1_error_t GrallocImpl::ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
  if (!device || !buffer) {
    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
  }

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

gralloc1_error_t GrallocImpl::GetFlexLayout(const private_handle_t *hnd,
                                            struct android_flex_layout *layout) {
  if (!IsYuvFormat(hnd->format)) {
    return 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 GRALLOC1_ERROR_NONE;
}

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

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

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

gralloc1_error_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
                                         gralloc1_producer_usage_t prod_usage,
                                         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 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 GRALLOC1_ERROR_UNDEFINED;
    }
  }

  const private_handle_t *hnd = PRIV_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 status;
}

gralloc1_error_t GrallocImpl::LockFlex(gralloc1_device_t *device, buffer_handle_t buffer,
                                       gralloc1_producer_usage_t prod_usage,
                                       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 GRALLOC1_ERROR_BAD_VALUE;
  }

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

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

gralloc1_error_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 status;
  }

  if (!release_fence) {
    return GRALLOC1_ERROR_BAD_VALUE;
  }

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

  *release_fence = -1;

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

static gralloc1_error_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 GRALLOC1_ERROR_BAD_VALUE;
      }

      BufferInfo info(width, width, format);
      GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
      *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 GRALLOC1_ERROR_BAD_HANDLE;
      }

      if (!stride) {
        return GRALLOC1_ERROR_BAD_VALUE;
      }

      BufferDim_t buffer_dim;
      if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
        *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 GRALLOC1_ERROR_BAD_HANDLE;
      }

      if (!stride || !height) {
        return GRALLOC1_ERROR_BAD_VALUE;
      }

      GetCustomDimensions(hnd, stride, height);
    } 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 GRALLOC1_ERROR_BAD_VALUE;
      }

      unsigned int alignedw, alignedh;
      BufferInfo info(width, height, format, usage);
      *tile_enabled = IsUBwcEnabled(format, usage);
      GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
      *aligned_width = INT(alignedw);
      *aligned_height = INT(alignedh);
    } break;

    case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_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 GRALLOC1_ERROR_BAD_HANDLE;
      }

      if (!color_space) {
        return 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 GRALLOC1_ERROR_BAD_HANDLE;
      }

      if (!ycbcr) {
        return GRALLOC1_ERROR_BAD_VALUE;
      }

      if (GetYUVPlaneInfo(hnd, ycbcr)) {
        return GRALLOC1_ERROR_UNDEFINED;
      }
    } break;

    case GRALLOC_MODULE_PERFORM_GET_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 GRALLOC1_ERROR_BAD_HANDLE;
      }

      if (!map_secure_buffer) {
        return GRALLOC1_ERROR_BAD_VALUE;
      }

      if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) != 0) {
        *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 GRALLOC1_ERROR_BAD_HANDLE;
      }

      if (!flag) {
        return GRALLOC1_ERROR_BAD_VALUE;
      }

      *flag = hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
      int linear_format = 0;
      if (getMetaData(hnd, GET_LINEAR_FORMAT, &linear_format) == 0) {
        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 GRALLOC1_ERROR_BAD_HANDLE;
      }

      if (!rgb_data) {
        return GRALLOC1_ERROR_BAD_VALUE;
      }

      if (GetRgbDataAddress(hnd, rgb_data)) {
        return 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 GRALLOC1_ERROR_BAD_HANDLE;
      }

      if (!flag) {
        return GRALLOC1_ERROR_BAD_VALUE;
      }

      if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
        *flag = 0;
      }
    } break;

    case GRALLOC_MODULE_PERFORM_SET_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 GRALLOC1_ERROR_BAD_HANDLE;
      }
      if (setMetaData(hnd, SET_SINGLE_BUFFER_MODE, enable) != 0) {
        return GRALLOC1_ERROR_UNSUPPORTED;
      }
    } 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;
  }
  return GRALLOC1_ERROR_NONE;
}

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

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

  return err;
}

}  // namespace gralloc
