summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2021-11-11 18:43:30 -0800
committerGravatar bunnei2022-03-24 18:13:32 -0700
commit79e8cdf595e1fe86f985b88c655aea277ba32692 (patch)
tree2baae902c2d9f8947af839a1a213bb95c2e4dff6 /src
parenthle: nvflinger: Add implementation for BufferSlot class. (diff)
downloadyuzu-79e8cdf595e1fe86f985b88c655aea277ba32692.tar.gz
yuzu-79e8cdf595e1fe86f985b88c655aea277ba32692.tar.xz
yuzu-79e8cdf595e1fe86f985b88c655aea277ba32692.zip
hle: nvflinger: Add implementation for ConsumerBase class.
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/service/nvflinger/consumer_base.cpp129
-rw-r--r--src/core/hle/service/nvflinger/consumer_base.h59
3 files changed, 190 insertions, 0 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index fd2777b11..44d6b3cf7 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -542,6 +542,8 @@ add_library(core STATIC
542 hle/service/nvflinger/buffer_queue_defs.h 542 hle/service/nvflinger/buffer_queue_defs.h
543 hle/service/nvflinger/buffer_slot.h 543 hle/service/nvflinger/buffer_slot.h
544 hle/service/nvflinger/buffer_transform_flags.h 544 hle/service/nvflinger/buffer_transform_flags.h
545 hle/service/nvflinger/consumer_base.cpp
546 hle/service/nvflinger/consumer_base.h
545 hle/service/nvflinger/consumer_listener.h 547 hle/service/nvflinger/consumer_listener.h
546 hle/service/nvflinger/nvflinger.cpp 548 hle/service/nvflinger/nvflinger.cpp
547 hle/service/nvflinger/nvflinger.h 549 hle/service/nvflinger/nvflinger.h
diff --git a/src/core/hle/service/nvflinger/consumer_base.cpp b/src/core/hle/service/nvflinger/consumer_base.cpp
new file mode 100644
index 000000000..127e5930b
--- /dev/null
+++ b/src/core/hle/service/nvflinger/consumer_base.cpp
@@ -0,0 +1,129 @@
1// SPDX-License-Identifier: GPL-3.0-or-later
2// Copyright 2021 yuzu Emulator Project
3// Copyright 2010 The Android Open Source Project
4// Parts of this implementation were base on:
5// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/ConsumerBase.cpp
6
7#include "common/assert.h"
8#include "common/logging/log.h"
9#include "core/hle/service/nvflinger/buffer_item.h"
10#include "core/hle/service/nvflinger/buffer_queue_consumer.h"
11#include "core/hle/service/nvflinger/buffer_queue_core.h"
12#include "core/hle/service/nvflinger/consumer_base.h"
13#include "core/hle/service/nvflinger/ui/graphic_buffer.h"
14
15namespace android {
16
17ConsumerBase::ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_)
18 : consumer{std::move(consumer_)} {}
19
20ConsumerBase::~ConsumerBase() {
21 std::unique_lock lock(mutex);
22
23 ASSERT_MSG(is_abandoned, "consumer is not abandoned!");
24}
25
26void ConsumerBase::Connect(bool controlled_by_app) {
27 consumer->Connect(shared_from_this(), controlled_by_app);
28}
29
30void ConsumerBase::FreeBufferLocked(s32 slot_index) {
31 LOG_DEBUG(Service_NVFlinger, "slot_index={}", slot_index);
32
33 slots[slot_index].graphic_buffer = nullptr;
34 slots[slot_index].fence = Fence::NoFence();
35 slots[slot_index].frame_number = 0;
36}
37
38void ConsumerBase::OnFrameAvailable(const BufferItem& item) {
39 std::unique_lock lock(mutex);
40 LOG_DEBUG(Service_NVFlinger, "called");
41}
42
43void ConsumerBase::OnFrameReplaced(const BufferItem& item) {
44 std::unique_lock lock(mutex);
45 LOG_DEBUG(Service_NVFlinger, "called");
46}
47
48void ConsumerBase::OnBuffersReleased() {
49 std::unique_lock lock(mutex);
50 LOG_DEBUG(Service_NVFlinger, "called");
51}
52
53void ConsumerBase::OnSidebandStreamChanged() {}
54
55Status ConsumerBase::AcquireBufferLocked(BufferItem* item, u64 present_when_ns,
56 u64 max_frame_number) {
57 if (is_abandoned) {
58 LOG_ERROR(Service_NVFlinger, "consumer is abandoned!");
59 return Status::NoInit;
60 }
61
62 Status err = consumer->AcquireBuffer(item, present_when_ns, max_frame_number);
63 if (err != Status::NoError) {
64 return err;
65 }
66
67 if (item->graphic_buffer != nullptr) {
68 if (slots[item->slot].graphic_buffer != nullptr) {
69 FreeBufferLocked(item->slot);
70 }
71 slots[item->slot].graphic_buffer = item->graphic_buffer;
72 }
73
74 slots[item->slot].frame_number = item->frame_number;
75 slots[item->slot].fence = item->fence;
76
77 LOG_DEBUG(Service_NVFlinger, "slot={}", item->slot);
78
79 return Status::NoError;
80}
81
82Status ConsumerBase::AddReleaseFenceLocked(s32 slot,
83 const std::shared_ptr<GraphicBuffer> graphic_buffer,
84 const Fence& fence) {
85 LOG_DEBUG(Service_NVFlinger, "slot={}", slot);
86
87 // If consumer no longer tracks this graphic_buffer, we can safely
88 // drop this fence, as it will never be received by the producer.
89
90 if (!StillTracking(slot, graphic_buffer)) {
91 return Status::NoError;
92 }
93
94 slots[slot].fence = fence;
95
96 return Status::NoError;
97}
98
99Status ConsumerBase::ReleaseBufferLocked(s32 slot,
100 const std::shared_ptr<GraphicBuffer> graphic_buffer) {
101 // If consumer no longer tracks this graphic_buffer (we received a new
102 // buffer on the same slot), the buffer producer is definitely no longer
103 // tracking it.
104
105 if (!StillTracking(slot, graphic_buffer)) {
106 return Status::NoError;
107 }
108
109 LOG_DEBUG(Service_NVFlinger, "slot={}", slot);
110 Status err = consumer->ReleaseBuffer(slot, slots[slot].frame_number, slots[slot].fence);
111 if (err == Status::StaleBufferSlot) {
112 FreeBufferLocked(slot);
113 }
114
115 slots[slot].fence = Fence::NoFence();
116
117 return err;
118}
119
120bool ConsumerBase::StillTracking(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer) {
121 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
122 return false;
123 }
124
125 return (slots[slot].graphic_buffer != nullptr &&
126 slots[slot].graphic_buffer->Handle() == graphic_buffer->Handle());
127}
128
129} // namespace android
diff --git a/src/core/hle/service/nvflinger/consumer_base.h b/src/core/hle/service/nvflinger/consumer_base.h
new file mode 100644
index 000000000..574ea9781
--- /dev/null
+++ b/src/core/hle/service/nvflinger/consumer_base.h
@@ -0,0 +1,59 @@
1// SPDX-License-Identifier: GPL-3.0-or-later
2// Copyright 2021 yuzu Emulator Project
3// Copyright 2010 The Android Open Source Project
4// Parts of this implementation were base on:
5// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/include/gui/ConsumerBase.h
6
7#pragma once
8
9#include <array>
10#include <memory>
11#include <mutex>
12
13#include "common/common_types.h"
14#include "core/hle/service/nvflinger/buffer_queue_defs.h"
15#include "core/hle/service/nvflinger/consumer_listener.h"
16#include "core/hle/service/nvflinger/status.h"
17
18namespace android {
19
20class BufferItem;
21class BufferQueueConsumer;
22
23class ConsumerBase : public IConsumerListener, public std::enable_shared_from_this<ConsumerBase> {
24public:
25 void Connect(bool controlled_by_app);
26
27protected:
28 ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_);
29 virtual ~ConsumerBase();
30
31 virtual void OnFrameAvailable(const BufferItem& item) override;
32 virtual void OnFrameReplaced(const BufferItem& item) override;
33 virtual void OnBuffersReleased() override;
34 virtual void OnSidebandStreamChanged() override;
35
36 void FreeBufferLocked(s32 slot_index);
37 Status AcquireBufferLocked(BufferItem* item, u64 present_when_ns, u64 max_frame_number = 0);
38 Status ReleaseBufferLocked(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer);
39 bool StillTracking(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer);
40 Status AddReleaseFenceLocked(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer,
41 const Fence& fence);
42
43 struct Slot final {
44 std::shared_ptr<GraphicBuffer> graphic_buffer;
45 Fence fence;
46 u64 frame_number{};
47 };
48
49protected:
50 std::array<Slot, BufferQueueDefs::NUM_BUFFER_SLOTS> slots;
51
52 bool is_abandoned{};
53
54 std::unique_ptr<BufferQueueConsumer> consumer;
55
56 mutable std::mutex mutex;
57};
58
59} // namespace android