#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
+#include "seperate_rects.h"
struct hwc_import_context;
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;
+ 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