/*
 * 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 "hwc-buffer-info-getter"

#include "BufferInfoGetter.h"

#if PLATFORM_SDK_VERSION >= 30
#include "BufferInfoMapperMetadata.h"
#endif

#include <xf86drm.h>
#include <xf86drmMode.h>

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

namespace android {

BufferInfoGetter *BufferInfoGetter::GetInstance() {
  static std::unique_ptr<BufferInfoGetter> inst;
  if (!inst) {
#if PLATFORM_SDK_VERSION >= 30 && defined(USE_IMAPPER4_METADATA_API)
    inst.reset(BufferInfoMapperMetadata::CreateInstance());
    if (!inst) {
      ALOGW(
          "Generic buffer getter is not available. Falling back to legacy...");
    }
#endif
    if (!inst) {
      inst = LegacyBufferInfoGetter::CreateInstance();
    }
  }

  return inst.get();
}

bool BufferInfoGetter::IsHandleUsable(buffer_handle_t handle) {
  hwc_drm_bo_t bo;
  memset(&bo, 0, sizeof(hwc_drm_bo_t));

  if (ConvertBoInfo(handle, &bo) != 0) {
    return false;
  }
  if (bo.prime_fds[0] == 0) {
    return false;
  }
  return true;
}

int LegacyBufferInfoGetter::Init() {
  int ret = hw_get_module(
      GRALLOC_HARDWARE_MODULE_ID,
      // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
      reinterpret_cast<const hw_module_t **>(&gralloc_));
  if (ret != 0) {
    ALOGE("Failed to open gralloc module");
    return ret;
  }

  ALOGI("Using %s gralloc module: %s\n", gralloc_->common.name,
        gralloc_->common.author);

  return 0;
}

uint32_t LegacyBufferInfoGetter::ConvertHalFormatToDrm(uint32_t hal_format) {
  switch (hal_format) {
    case HAL_PIXEL_FORMAT_RGB_888:
      return DRM_FORMAT_BGR888;
    case HAL_PIXEL_FORMAT_BGRA_8888:
      return DRM_FORMAT_ARGB8888;
    case HAL_PIXEL_FORMAT_RGBX_8888:
      return DRM_FORMAT_XBGR8888;
    case HAL_PIXEL_FORMAT_RGBA_8888:
      return DRM_FORMAT_ABGR8888;
    case HAL_PIXEL_FORMAT_RGB_565:
      return DRM_FORMAT_BGR565;
    case HAL_PIXEL_FORMAT_YV12:
      return DRM_FORMAT_YVU420;
    case HAL_PIXEL_FORMAT_RGBA_1010102:
      return DRM_FORMAT_ABGR2101010;
    default:
      ALOGE("Cannot convert hal format to drm format %u", hal_format);
      return DRM_FORMAT_INVALID;
  }
}

bool BufferInfoGetter::IsDrmFormatRgb(uint32_t drm_format) {
  switch (drm_format) {
    case DRM_FORMAT_ARGB8888:
    case DRM_FORMAT_XBGR8888:
    case DRM_FORMAT_ABGR8888:
    case DRM_FORMAT_BGR888:
    case DRM_FORMAT_BGR565:
    case DRM_FORMAT_ABGR2101010:
      return true;
    default:
      return false;
  }
}

__attribute__((weak)) std::unique_ptr<LegacyBufferInfoGetter>
LegacyBufferInfoGetter::CreateInstance() {
  ALOGE("No legacy buffer info getters available");
  return nullptr;
}

}  // namespace android
