/*
 * Copyright (C) 2015 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.
 */

#ifndef ANDROID_DRM_HWCOMPOSER_H_
#define ANDROID_DRM_HWCOMPOSER_H_

#include <stdbool.h>
#include <stdint.h>

#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
#include "seperate_rects.h"
#include "drmhwcgralloc.h"

struct hwc_import_context;

int hwc_import_init(struct hwc_import_context **ctx);
int hwc_import_destroy(struct hwc_import_context *ctx);

int hwc_import_bo_create(int fd, struct hwc_import_context *ctx,
                         buffer_handle_t buf, struct hwc_drm_bo *bo);
bool hwc_import_bo_release(int fd, struct hwc_import_context *ctx,
                           struct hwc_drm_bo *bo);

namespace android {

class Importer;

class UniqueFd {
 public:
  UniqueFd() = default;
  UniqueFd(int fd) : fd_(fd) {
  }
  UniqueFd(UniqueFd &&rhs) {
    fd_ = rhs.fd_;
    rhs.fd_ = -1;
  }

  UniqueFd &operator=(UniqueFd &&rhs) {
    Set(rhs.Release());
    return *this;
  }

  ~UniqueFd() {
    if (fd_ >= 0)
      close(fd_);
  }

  int Release() {
    int old_fd = fd_;
    fd_ = -1;
    return old_fd;
  }

  int Set(int fd) {
    if (fd_ >= 0)
      close(fd_);
    fd_ = fd;
    return fd_;
  }

  void Close() {
    if (fd_ >= 0)
      close(fd_);
    fd_ = -1;
  }

  int get() {
    return fd_;
  }

 private:
  int fd_ = -1;
};

struct OutputFd {
  OutputFd() = default;
  OutputFd(int *fd) : fd_(fd) {
  }
  OutputFd(OutputFd &&rhs) {
    fd_ = rhs.fd_;
    rhs.fd_ = NULL;
  }

  OutputFd &operator=(OutputFd &&rhs);

  int Set(int fd) {
    if (*fd_ >= 0)
      close(*fd_);
    *fd_ = fd;
    return fd;
  }

  int get() {
    return *fd_;
  }

 private:
  int *fd_ = NULL;
};

class DrmHwcBuffer {
 public:
  DrmHwcBuffer() = default;
  DrmHwcBuffer(const hwc_drm_bo &bo, Importer *importer)
      : bo_(bo), importer_(importer) {
  }
  DrmHwcBuffer(DrmHwcBuffer &&rhs) : bo_(rhs.bo_), importer_(rhs.importer_) {
    rhs.importer_ = NULL;
  }

  ~DrmHwcBuffer() {
    Clear();
  }

  DrmHwcBuffer &operator=(DrmHwcBuffer &&rhs) {
    Clear();
    importer_ = rhs.importer_;
    rhs.importer_ = NULL;
    bo_ = rhs.bo_;
    return *this;
  }

  operator bool() const {
    return importer_ != NULL;
  }

  const hwc_drm_bo *operator->() const;

  void Clear();

  int ImportBuffer(buffer_handle_t handle, Importer *importer);

 private:
  hwc_drm_bo bo_;
  Importer *importer_ = NULL;
};

class DrmHwcNativeHandle {
 public:
  DrmHwcNativeHandle() = default;

  DrmHwcNativeHandle(const gralloc_module_t *gralloc, native_handle_t *handle)
      : gralloc_(gralloc), handle_(handle) {
  }

  DrmHwcNativeHandle(DrmHwcNativeHandle &&rhs) {
    gralloc_ = rhs.gralloc_;
    rhs.gralloc_ = NULL;
    handle_ = rhs.handle_;
    rhs.handle_ = NULL;
  }

  ~DrmHwcNativeHandle();

  DrmHwcNativeHandle &operator=(DrmHwcNativeHandle &&rhs) {
    Clear();
    gralloc_ = rhs.gralloc_;
    rhs.gralloc_ = NULL;
    handle_ = rhs.handle_;
    rhs.handle_ = NULL;
    return *this;
  }

  int CopyBufferHandle(buffer_handle_t handle, const gralloc_module_t *gralloc);

  void Clear();

  buffer_handle_t get() const {
    return handle_;
  }

 private:
  const gralloc_module_t *gralloc_ = NULL;
  native_handle_t *handle_ = NULL;
};

template <typename T>
using DrmHwcRect = seperate_rects::Rect<T>;

enum class DrmHwcTransform : uint32_t {
  kIdentity = 0,
  kFlipH = HWC_TRANSFORM_FLIP_H,
  kFlipV = HWC_TRANSFORM_FLIP_V,
  kRotate90 = HWC_TRANSFORM_ROT_90,
  kRotate180 = HWC_TRANSFORM_ROT_180,
  kRotate270 = HWC_TRANSFORM_ROT_270,
};

enum class DrmHwcBlending : int32_t {
  kNone = HWC_BLENDING_NONE,
  kPreMult = HWC_BLENDING_PREMULT,
  kCoverage = HWC_BLENDING_COVERAGE,
};

struct DrmHwcLayer {
  buffer_handle_t sf_handle = NULL;
  int gralloc_buffer_usage = 0;
  DrmHwcBuffer buffer;
  DrmHwcNativeHandle handle;
  DrmHwcTransform transform = DrmHwcTransform::kIdentity;
  DrmHwcBlending blending = DrmHwcBlending::kNone;
  uint8_t alpha = 0xff;
  DrmHwcRect<float> source_crop;
  DrmHwcRect<int> display_frame;
  std::vector<DrmHwcRect<int>> source_damage;

  UniqueFd acquire_fence;
  OutputFd release_fence;

  int InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer,
                       const gralloc_module_t *gralloc);

  buffer_handle_t get_usable_handle() const {
    return handle.get() != NULL ? handle.get() : sf_handle;
  }
};

struct DrmHwcDisplayContents {
  OutputFd retire_fence;
  std::vector<DrmHwcLayer> layers;
};
}

#endif
