From 00571590663f73b7bfb659f78d6cc59473113a5a Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Thu, 11 Nov 2021 18:46:56 -0800
Subject: [PATCH] hle: nvflinger: Add implementation for BufferItemConsumer
 class.

---
 src/core/CMakeLists.txt                       |  2 +
 .../nvflinger/buffer_item_consumer.cpp        | 59 +++++++++++++++++++
 .../service/nvflinger/buffer_item_consumer.h  | 26 ++++++++
 3 files changed, 87 insertions(+)
 create mode 100644 src/core/hle/service/nvflinger/buffer_item_consumer.cpp
 create mode 100644 src/core/hle/service/nvflinger/buffer_item_consumer.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 44d6b3cf75..78b1e68ead 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -539,6 +539,8 @@ add_library(core STATIC
     hle/service/nvflinger/buffer_queue.h
     hle/service/nvflinger/binder.h
     hle/service/nvflinger/buffer_item.h
+    hle/service/nvflinger/buffer_item_consumer.cpp
+    hle/service/nvflinger/buffer_item_consumer.h
     hle/service/nvflinger/buffer_queue_defs.h
     hle/service/nvflinger/buffer_slot.h
     hle/service/nvflinger/buffer_transform_flags.h
diff --git a/src/core/hle/service/nvflinger/buffer_item_consumer.cpp b/src/core/hle/service/nvflinger/buffer_item_consumer.cpp
new file mode 100644
index 0000000000..424b19d32e
--- /dev/null
+++ b/src/core/hle/service/nvflinger/buffer_item_consumer.cpp
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+// Copyright 2021 yuzu Emulator Project
+// Copyright 2012 The Android Open Source Project
+// Parts of this implementation were base on:
+// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferItemConsumer.cpp
+
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "core/hle/service/nvflinger/buffer_item.h"
+#include "core/hle/service/nvflinger/buffer_item_consumer.h"
+#include "core/hle/service/nvflinger/buffer_queue_consumer.h"
+
+namespace android {
+
+BufferItemConsumer::BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer_)
+    : ConsumerBase{std::move(consumer_)} {}
+
+Status BufferItemConsumer::AcquireBuffer(BufferItem* item, u64 present_when_ns,
+                                         bool wait_for_fence) {
+    if (!item) {
+        return Status::BadValue;
+    }
+
+    std::unique_lock lock(mutex);
+
+    if (const auto status = AcquireBufferLocked(item, present_when_ns); status != Status::NoError) {
+        if (status != Status::NoBufferAvailable) {
+            LOG_ERROR(Service_NVFlinger, "Failed to acquire buffer: {}", status);
+        }
+        return status;
+    }
+
+    if (wait_for_fence) {
+        UNIMPLEMENTED();
+    }
+
+    item->graphic_buffer = slots[item->slot].graphic_buffer;
+
+    return Status::NoError;
+}
+
+Status BufferItemConsumer::ReleaseBuffer(const BufferItem& item, Fence& release_fence) {
+    std::unique_lock lock(mutex);
+
+    if (const auto status = AddReleaseFenceLocked(item.buf, item.graphic_buffer, release_fence);
+        status != Status::NoError) {
+        LOG_ERROR(Service_NVFlinger, "Failed to add fence: {}", status);
+    }
+
+    if (const auto status = ReleaseBufferLocked(item.buf, item.graphic_buffer);
+        status != Status::NoError) {
+        LOG_WARNING(Service_NVFlinger, "Failed to release buffer: {}", status);
+        return status;
+    }
+
+    return Status::NoError;
+}
+
+} // namespace android
diff --git a/src/core/hle/service/nvflinger/buffer_item_consumer.h b/src/core/hle/service/nvflinger/buffer_item_consumer.h
new file mode 100644
index 0000000000..f61c180b30
--- /dev/null
+++ b/src/core/hle/service/nvflinger/buffer_item_consumer.h
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+// Copyright 2021 yuzu Emulator Project
+// Copyright 2012 The Android Open Source Project
+// Parts of this implementation were base on:
+// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/BufferItemConsumer.h
+
+#pragma once
+
+#include <memory>
+
+#include "common/common_types.h"
+#include "core/hle/service/nvflinger/consumer_base.h"
+#include "core/hle/service/nvflinger/status.h"
+
+namespace android {
+
+class BufferItem;
+
+class BufferItemConsumer final : public ConsumerBase {
+public:
+    explicit BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer);
+    Status AcquireBuffer(BufferItem* item, u64 present_when_ns, bool wait_for_fence = true);
+    Status ReleaseBuffer(const BufferItem& item, Fence& release_fence);
+};
+
+} // namespace android