/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "drmhwc"

#include "BufferInfoLibdrm.h"

#include <gralloc_handle.h>
#include <hardware/gralloc.h>
#include <xf86drm.h>
#include <xf86drmMode.h>

#include <mutex>

#include "utils/log.h"
#include "utils/properties.h"

namespace android {

LEGACY_BUFFER_INFO_GETTER(BufferInfoLibdrm);

enum chroma_order {
  kYCbCr,
  kYCrCb,
};

struct DroidYuvFormat {
  /* Lookup keys */
  uint32_t native;                /* HAL_PIXEL_FORMAT_ */
  enum chroma_order chroma_order; /* chroma order is {Cb, Cr} or {Cr, Cb} */
  size_t chroma_step; /* Distance in bytes between subsequent chroma pixels. */

  /* Result */
  int fourcc; /* DRM_FORMAT_ */
};

#ifndef DRM_FORMAT_XYUV8888
#define DRM_FORMAT_XYUV8888 \
  fourcc_code('X', 'Y', 'U', 'V') /* [31:0] X:Y:Cb:Cr 8:8:8:8 little endian */
#endif

/* The following table is used to look up a DRI image FourCC based
 * on native format and information contained in android_ycbcr struct. */
static const struct DroidYuvFormat kDroidYuvFormats[] = {
    /* Native format, YCrCb, Chroma step, DRI image FourCC */
    {HAL_PIXEL_FORMAT_YCbCr_420_888, kYCbCr, 2, DRM_FORMAT_NV12},
    {HAL_PIXEL_FORMAT_YCbCr_420_888, kYCbCr, 1, DRM_FORMAT_YUV420},
    {HAL_PIXEL_FORMAT_YCbCr_420_888, kYCrCb, 1, DRM_FORMAT_YVU420},
    {HAL_PIXEL_FORMAT_YV12, kYCrCb, 1, DRM_FORMAT_YVU420},
    /* HACK: See droid_create_image_from_prime_fds() and
     * https://issuetracker.google.com/32077885. */
    {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, kYCbCr, 2, DRM_FORMAT_NV12},
    {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, kYCbCr, 1, DRM_FORMAT_YUV420},
    {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, kYCrCb, 1, DRM_FORMAT_YVU420},
    {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, kYCrCb, 1, DRM_FORMAT_AYUV},
    {HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, kYCrCb, 1, DRM_FORMAT_XYUV8888},
};

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

static uint32_t get_fourcc_yuv(uint32_t native, enum chroma_order chroma_order,
                               size_t chroma_step) {
  for (auto droid_yuv_format : kDroidYuvFormats)
    if (droid_yuv_format.native == native &&
        droid_yuv_format.chroma_order == chroma_order &&
        droid_yuv_format.chroma_step == chroma_step)
      return droid_yuv_format.fourcc;

  return UINT32_MAX;
}

static bool is_yuv(uint32_t native) {
  // NOLINTNEXTLINE(readability-use-anyofallof)
  for (auto droid_yuv_format : kDroidYuvFormats)
    if (droid_yuv_format.native == native)
      return true;

  return false;
}

bool BufferInfoLibdrm::GetYuvPlaneInfo(uint32_t hal_format, int num_fds,
                                       buffer_handle_t handle, BufferInfo *bo) {
  struct android_ycbcr ycbcr {};
  enum chroma_order chroma_order {};
  int ret = 0;

  if (!gralloc_->lock_ycbcr) {
    static std::once_flag once;
    std::call_once(once,
                   []() { ALOGW("Gralloc does not support lock_ycbcr()"); });
    return false;
  }

  memset(&ycbcr, 0, sizeof(ycbcr));
  ret = gralloc_->lock_ycbcr(gralloc_, handle, 0, 0, 0, 0, 0, &ycbcr);
  if (ret) {
    ALOGW("gralloc->lock_ycbcr failed: %d", ret);
    return false;
  }
  gralloc_->unlock(gralloc_, handle);

  /* When lock_ycbcr's usage argument contains no SW_READ/WRITE flags
   * it will return the .y/.cb/.cr pointers based on a NULL pointer,
   * so they can be interpreted as offsets. */
  bo->offsets[0] = (size_t)ycbcr.y;
  /* We assume here that all the planes are located in one DMA-buf. */
  if ((size_t)ycbcr.cr < (size_t)ycbcr.cb) {
    chroma_order = kYCrCb;
    bo->offsets[1] = (size_t)ycbcr.cr;
    bo->offsets[2] = (size_t)ycbcr.cb;
  } else {
    chroma_order = kYCbCr;
    bo->offsets[1] = (size_t)ycbcr.cb;
    bo->offsets[2] = (size_t)ycbcr.cr;
  }

  /* .ystride is the line length (in bytes) of the Y plane,
   * .cstride is the line length (in bytes) of any of the remaining
   * Cb/Cr/CbCr planes, assumed to be the same for Cb and Cr for fully
   * planar formats. */
  bo->pitches[0] = ycbcr.ystride;
  bo->pitches[1] = bo->pitches[2] = ycbcr.cstride;

  /* .chroma_step is the byte distance between the same chroma channel
   * values of subsequent pixels, assumed to be the same for Cb and Cr. */
  bo->format = get_fourcc_yuv(hal_format, chroma_order, ycbcr.chroma_step);
  if (bo->format == UINT32_MAX) {
    ALOGW(
        "unsupported YUV format, native = %x, chroma_order = %s, chroma_step = "
        "%d",
        hal_format, chroma_order == kYCbCr ? "YCbCr" : "YCrCb",
        (int)ycbcr.chroma_step);
    return false;
  }

  /*
   * Since this is EGL_NATIVE_BUFFER_ANDROID don't assume that
   * the single-fd case cannot happen.  So handle eithe single
   * fd or fd-per-plane case:
   */
  if (num_fds == 1) {
    bo->prime_fds[2] = bo->prime_fds[1] = bo->prime_fds[0];
  } else {
    const int expected_planes = (ycbcr.chroma_step == 2) ? 2 : 3;
    if (num_fds != expected_planes)
      return false;
  }

  return true;
}

auto BufferInfoLibdrm::GetBoInfo(buffer_handle_t handle)
    -> std::optional<BufferInfo> {
  gralloc_handle_t *gr_handle = gralloc_handle(handle);
  if (!gr_handle)
    return {};

  BufferInfo bi{};

  bi.width = gr_handle->width;
  bi.height = gr_handle->height;

#if GRALLOC_HANDLE_VERSION < 4
  static std::once_flag once;
  std::call_once(once, []() {
    ALOGE(
        "libdrm < v2.4.97 has broken gralloc_handle structure. Please update.");
  });
#endif
#if GRALLOC_HANDLE_VERSION == 4
  bi.modifiers[0] = gr_handle->modifier;
#endif

  bi.prime_fds[0] = gr_handle->prime_fd;

  if (is_yuv(gr_handle->format)) {
    if (!GetYuvPlaneInfo(gr_handle->format, handle->numFds, handle, &bi))
      return {};
  } else {
    bi.pitches[0] = gr_handle->stride;
    bi.offsets[0] = 0;

    /* FOSS graphic components (gbm_gralloc, mesa3d) are translating
     * HAL_PIXEL_FORMAT_RGB_565 to DRM_FORMAT_RGB565 without swapping
     * the R and B components. Same must be done here. */
    switch (gr_handle->format) {
      case HAL_PIXEL_FORMAT_RGB_565:
        bi.format = DRM_FORMAT_RGB565;
        break;
      default:
        bi.format = ConvertHalFormatToDrm(gr_handle->format);
    }

    if (bi.format == DRM_FORMAT_INVALID)
      return {};
  }

  return bi;
}

constexpr char gbm_gralloc_module_name[] = "GBM Memory Allocator";
constexpr char drm_gralloc_module_name[] = "DRM Memory Allocator";

int BufferInfoLibdrm::ValidateGralloc() {
  if (strcmp(gralloc_->common.name, drm_gralloc_module_name) != 0 &&
      strcmp(gralloc_->common.name, gbm_gralloc_module_name) != 0) {
    ALOGE(
        "Gralloc name isn't valid: Expected: \"%s\" or \"%s\", Actual: \"%s\"",
        gbm_gralloc_module_name, drm_gralloc_module_name,
        gralloc_->common.name);
    return -EINVAL;
  }

  return 0;
}

}  // namespace android
