forked from suyu/suyu
hle: service: nvflinger: buffer_queue_producer: Cleanup & add GetReleasedBuffers.
This commit is contained in:
parent
7610554b1e
commit
30b07878ba
2 changed files with 38 additions and 10 deletions
|
@ -18,8 +18,7 @@ BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_)
|
||||||
BufferQueueConsumer::~BufferQueueConsumer() = default;
|
BufferQueueConsumer::~BufferQueueConsumer() = default;
|
||||||
|
|
||||||
Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
|
Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
|
||||||
std::chrono::nanoseconds expected_present,
|
std::chrono::nanoseconds expected_present) {
|
||||||
u64 max_frame_number) {
|
|
||||||
std::scoped_lock lock(core->mutex);
|
std::scoped_lock lock(core->mutex);
|
||||||
|
|
||||||
// Check that the consumer doesn't currently have the maximum number of buffers acquired.
|
// Check that the consumer doesn't currently have the maximum number of buffers acquired.
|
||||||
|
@ -50,12 +49,6 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
|
||||||
while (core->queue.size() > 1 && !core->queue[0].is_auto_timestamp) {
|
while (core->queue.size() > 1 && !core->queue[0].is_auto_timestamp) {
|
||||||
const auto& buffer_item{core->queue[1]};
|
const auto& buffer_item{core->queue[1]};
|
||||||
|
|
||||||
// If dropping entry[0] would leave us with a buffer that the consumer is not yet ready
|
|
||||||
// for, don't drop it.
|
|
||||||
if (max_frame_number && buffer_item.frame_number > max_frame_number) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If entry[1] is timely, drop entry[0] (and repeat).
|
// If entry[1] is timely, drop entry[0] (and repeat).
|
||||||
const auto desired_present = buffer_item.timestamp;
|
const auto desired_present = buffer_item.timestamp;
|
||||||
if (desired_present < expected_present.count() - MAX_REASONABLE_NSEC ||
|
if (desired_present < expected_present.count() - MAX_REASONABLE_NSEC ||
|
||||||
|
@ -200,4 +193,39 @@ Status BufferQueueConsumer::Connect(std::shared_ptr<IConsumerListener> consumer_
|
||||||
return Status::NoError;
|
return Status::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) {
|
||||||
|
if (out_slot_mask == nullptr) {
|
||||||
|
LOG_ERROR(Service_NVFlinger, "out_slot_mask may not be nullptr");
|
||||||
|
return Status::BadValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::scoped_lock lock(core->mutex);
|
||||||
|
|
||||||
|
if (core->is_abandoned) {
|
||||||
|
LOG_ERROR(Service_NVFlinger, "BufferQueue has been abandoned");
|
||||||
|
return Status::NoInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 mask = 0;
|
||||||
|
for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
|
||||||
|
if (!slots[s].acquire_called) {
|
||||||
|
mask |= (1ULL << s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove from the mask queued buffers for which acquire has been called, since the consumer
|
||||||
|
// will not receive their buffer addresses and so must retain their cached information
|
||||||
|
auto current(core->queue.begin());
|
||||||
|
while (current != core->queue.end()) {
|
||||||
|
if (current->acquire_called) {
|
||||||
|
mask &= ~(1ULL << current->slot);
|
||||||
|
}
|
||||||
|
++current;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_NVFlinger, "returning mask {}", mask);
|
||||||
|
*out_slot_mask = mask;
|
||||||
|
return Status::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Service::android
|
} // namespace Service::android
|
||||||
|
|
|
@ -24,10 +24,10 @@ public:
|
||||||
explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_);
|
explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_);
|
||||||
~BufferQueueConsumer();
|
~BufferQueueConsumer();
|
||||||
|
|
||||||
Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present,
|
Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present);
|
||||||
u64 max_frame_number = 0);
|
|
||||||
Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence);
|
Status ReleaseBuffer(s32 slot, u64 frame_number, const Fence& release_fence);
|
||||||
Status Connect(std::shared_ptr<IConsumerListener> consumer_listener, bool controlled_by_app);
|
Status Connect(std::shared_ptr<IConsumerListener> consumer_listener, bool controlled_by_app);
|
||||||
|
Status GetReleasedBuffers(u64* out_slot_mask);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<BufferQueueCore> core;
|
std::shared_ptr<BufferQueueCore> core;
|
||||||
|
|
Loading…
Reference in a new issue