diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue_consumer.cpp | 44 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue_consumer.h | 4 |
2 files changed, 38 insertions, 10 deletions
diff --git a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp index 41fbba219..c527c577e 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp | |||
| @@ -18,8 +18,7 @@ BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_) | |||
| 18 | BufferQueueConsumer::~BufferQueueConsumer() = default; | 18 | BufferQueueConsumer::~BufferQueueConsumer() = default; |
| 19 | 19 | ||
| 20 | Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, | 20 | Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, |
| 21 | std::chrono::nanoseconds expected_present, | 21 | std::chrono::nanoseconds expected_present) { |
| 22 | u64 max_frame_number) { | ||
| 23 | std::scoped_lock lock(core->mutex); | 22 | std::scoped_lock lock(core->mutex); |
| 24 | 23 | ||
| 25 | // Check that the consumer doesn't currently have the maximum number of buffers acquired. | 24 | // Check that the consumer doesn't currently have the maximum number of buffers acquired. |
| @@ -50,12 +49,6 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, | |||
| 50 | while (core->queue.size() > 1 && !core->queue[0].is_auto_timestamp) { | 49 | while (core->queue.size() > 1 && !core->queue[0].is_auto_timestamp) { |
| 51 | const auto& buffer_item{core->queue[1]}; | 50 | const auto& buffer_item{core->queue[1]}; |
| 52 | 51 | ||
| 53 | // If dropping entry[0] would leave us with a buffer that the consumer is not yet ready | ||
| 54 | // for, don't drop it. | ||
| 55 | if (max_frame_number && buffer_item.frame_number > max_frame_number) { | ||
| 56 | break; | ||
| 57 | } | ||
| 58 | |||
| 59 | // If entry[1] is timely, drop entry[0] (and repeat). | 52 | // If entry[1] is timely, drop entry[0] (and repeat). |
| 60 | const auto desired_present = buffer_item.timestamp; | 53 | const auto desired_present = buffer_item.timestamp; |
| 61 | if (desired_present < expected_present.count() - MAX_REASONABLE_NSEC || | 54 | if (desired_present < expected_present.count() - MAX_REASONABLE_NSEC || |
| @@ -200,4 +193,39 @@ Status BufferQueueConsumer::Connect(std::shared_ptr<IConsumerListener> consumer_ | |||
| 200 | return Status::NoError; | 193 | return Status::NoError; |
| 201 | } | 194 | } |
| 202 | 195 | ||
| 196 | Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) { | ||
| 197 | if (out_slot_mask == nullptr) { | ||
| 198 | LOG_ERROR(Service_NVFlinger, "out_slot_mask may not be nullptr"); | ||
| 199 | return Status::BadValue; | ||
| 200 | } | ||
| 201 | |||
| 202 | std::scoped_lock lock(core->mutex); | ||
| 203 | |||
| 204 | if (core->is_abandoned) { | ||
| 205 | LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned"); | ||
| 206 | return Status::NoInit; | ||
| 207 | } | ||
| 208 | |||
| 209 | u64 mask = 0; | ||
| 210 | for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { | ||
| 211 | if (!slots[s].acquire_called) { | ||
| 212 | mask |= (1ULL << s); | ||
| 213 | } | ||
| 214 | } | ||
| 215 | |||
| 216 | // Remove from the mask queued buffers for which acquire has been called, since the consumer | ||
| 217 | // will not receive their buffer addresses and so must retain their cached information | ||
| 218 | auto current(core->queue.begin()); | ||
| 219 | while (current != core->queue.end()) { | ||
| 220 | if (current->acquire_called) { | ||
| 221 | mask &= ~(1ULL << current->slot); | ||
| 222 | } | ||
| 223 | ++current; | ||
| 224 | } | ||
| 225 | |||
| 226 | LOG_DEBUG(Service_NVFlinger, "returning mask {}", mask); | ||
| 227 | *out_slot_mask = mask; | ||
| 228 | return Status::NoError; | ||
| 229 | } | ||
| 230 | |||
| 203 | } // namespace Service::android | 231 | } // namespace Service::android |
diff --git a/src/core/hle/service/nvflinger/buffer_queue_consumer.h b/src/core/hle/service/nvflinger/buffer_queue_consumer.h index f22854394..8a047fe06 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_consumer.h +++ b/src/core/hle/service/nvflinger/buffer_queue_consumer.h | |||
| @@ -24,10 +24,10 @@ public: | |||
| 24 | explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_); | 24 | explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_); |
| 25 | ~BufferQueueConsumer(); | 25 | ~BufferQueueConsumer(); |
| 26 | 26 | ||
| 27 | Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present, | 27 | Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present); |
| 28 | u64 max_frame_number = 0); | ||
| 29 | Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence); | 28 | Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence); |
| 30 | Status Connect(std::shared_ptr<IConsumerListener> consumer_listener, bool controlled_by_app); | 29 | Status Connect(std::shared_ptr<IConsumerListener> consumer_listener, bool controlled_by_app); |
| 30 | Status GetReleasedBuffers(u64* out_slot_mask); | ||
| 31 | 31 | ||
| 32 | private: | 32 | private: |
| 33 | std::shared_ptr<BufferQueueCore> core; | 33 | std::shared_ptr<BufferQueueCore> core; |