mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-29 06:46:22 -05:00
hle: nvflinger: Use std::chrono for present_ns.
This commit is contained in:
parent
ca12a77670
commit
650c9d0d62
7 changed files with 30 additions and 25 deletions
|
@ -15,7 +15,7 @@ namespace Service::android {
|
||||||
BufferItemConsumer::BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer_)
|
BufferItemConsumer::BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer_)
|
||||||
: ConsumerBase{std::move(consumer_)} {}
|
: ConsumerBase{std::move(consumer_)} {}
|
||||||
|
|
||||||
Status BufferItemConsumer::AcquireBuffer(BufferItem* item, u64 present_when_ns,
|
Status BufferItemConsumer::AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when,
|
||||||
bool wait_for_fence) {
|
bool wait_for_fence) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return Status::BadValue;
|
return Status::BadValue;
|
||||||
|
@ -23,7 +23,7 @@ Status BufferItemConsumer::AcquireBuffer(BufferItem* item, u64 present_when_ns,
|
||||||
|
|
||||||
std::unique_lock lock(mutex);
|
std::unique_lock lock(mutex);
|
||||||
|
|
||||||
if (const auto status = AcquireBufferLocked(item, present_when_ns); status != Status::NoError) {
|
if (const auto status = AcquireBufferLocked(item, present_when); status != Status::NoError) {
|
||||||
if (status != Status::NoBufferAvailable) {
|
if (status != Status::NoBufferAvailable) {
|
||||||
LOG_ERROR(Service_NVFlinger, "Failed to acquire buffer: {}", status);
|
LOG_ERROR(Service_NVFlinger, "Failed to acquire buffer: {}", status);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -19,7 +20,8 @@ class BufferItem;
|
||||||
class BufferItemConsumer final : public ConsumerBase {
|
class BufferItemConsumer final : public ConsumerBase {
|
||||||
public:
|
public:
|
||||||
explicit BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer);
|
explicit BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer);
|
||||||
Status AcquireBuffer(BufferItem* item, u64 present_when_ns, bool wait_for_fence = true);
|
Status AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when,
|
||||||
|
bool wait_for_fence = true);
|
||||||
Status ReleaseBuffer(const BufferItem& item, Fence& release_fence);
|
Status ReleaseBuffer(const BufferItem& item, Fence& release_fence);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@ BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_)
|
||||||
|
|
||||||
BufferQueueConsumer::~BufferQueueConsumer() = default;
|
BufferQueueConsumer::~BufferQueueConsumer() = default;
|
||||||
|
|
||||||
Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, s64 expected_presenst_ns,
|
Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
|
||||||
|
std::chrono::nanoseconds expected_present,
|
||||||
u64 max_frame_number) {
|
u64 max_frame_number) {
|
||||||
s32 num_dropped_buffers{};
|
s32 num_dropped_buffers{};
|
||||||
|
|
||||||
|
@ -26,12 +27,10 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, s64 expected_p
|
||||||
std::unique_lock lock(core->mutex);
|
std::unique_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.
|
||||||
s32 num_acquired_buffers{};
|
const s32 num_acquired_buffers{
|
||||||
for (const auto& slot : slots) {
|
static_cast<s32>(std::count_if(slots.begin(), slots.end(), [](const auto& slot) {
|
||||||
if (slot.buffer_state == BufferState::Acquired) {
|
return slot.buffer_state == BufferState::Acquired;
|
||||||
++num_acquired_buffers;
|
}))};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_acquired_buffers >= core->max_acquired_buffer_count + 1) {
|
if (num_acquired_buffers >= core->max_acquired_buffer_count + 1) {
|
||||||
LOG_ERROR(Service_NVFlinger, "max acquired buffer count reached: {} (max {})",
|
LOG_ERROR(Service_NVFlinger, "max acquired buffer count reached: {} (max {})",
|
||||||
|
@ -46,8 +45,8 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, s64 expected_p
|
||||||
|
|
||||||
auto front(core->queue.begin());
|
auto front(core->queue.begin());
|
||||||
|
|
||||||
// If expected_presenst_ns is specified, we may not want to return a buffer yet.
|
// If expected_present is specified, we may not want to return a buffer yet.
|
||||||
if (expected_presenst_ns != 0) {
|
if (expected_present.count() != 0) {
|
||||||
constexpr auto MAX_REASONABLE_NSEC = 1000000000LL; // 1 second
|
constexpr auto MAX_REASONABLE_NSEC = 1000000000LL; // 1 second
|
||||||
|
|
||||||
// The expected_presenst_ns argument indicates when the buffer is expected to be
|
// The expected_presenst_ns argument indicates when the buffer is expected to be
|
||||||
|
@ -63,17 +62,17 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, s64 expected_p
|
||||||
|
|
||||||
// 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_presenst_ns - MAX_REASONABLE_NSEC ||
|
if (desired_present < expected_present.count() - MAX_REASONABLE_NSEC ||
|
||||||
desired_present > expected_presenst_ns) {
|
desired_present > expected_present.count()) {
|
||||||
// This buffer is set to display in the near future, or desired_present is
|
// This buffer is set to display in the near future, or desired_present is
|
||||||
// garbage.
|
// garbage.
|
||||||
LOG_DEBUG(Service_NVFlinger, "nodrop desire={} expect={}", desired_present,
|
LOG_DEBUG(Service_NVFlinger, "nodrop desire={} expect={}", desired_present,
|
||||||
expected_presenst_ns);
|
expected_present.count());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG(Service_NVFlinger, "drop desire={} expect={} size={}", desired_present,
|
LOG_DEBUG(Service_NVFlinger, "drop desire={} expect={} size={}", desired_present,
|
||||||
expected_presenst_ns, core->queue.size());
|
expected_present.count(), core->queue.size());
|
||||||
|
|
||||||
if (core->StillTracking(&*front)) {
|
if (core->StillTracking(&*front)) {
|
||||||
// Front buffer is still in mSlots, so mark the slot as free
|
// Front buffer is still in mSlots, so mark the slot as free
|
||||||
|
@ -89,19 +88,20 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, s64 expected_p
|
||||||
|
|
||||||
// See if the front buffer is ready to be acquired.
|
// See if the front buffer is ready to be acquired.
|
||||||
const auto desired_present = front->timestamp;
|
const auto desired_present = front->timestamp;
|
||||||
const auto buffer_is_due = desired_present <= expected_presenst_ns ||
|
const auto buffer_is_due =
|
||||||
desired_present > expected_presenst_ns + MAX_REASONABLE_NSEC;
|
desired_present <= expected_present.count() ||
|
||||||
|
desired_present > expected_present.count() + MAX_REASONABLE_NSEC;
|
||||||
const auto consumer_is_ready =
|
const auto consumer_is_ready =
|
||||||
max_frame_number > 0 ? front->frame_number <= max_frame_number : true;
|
max_frame_number > 0 ? front->frame_number <= max_frame_number : true;
|
||||||
|
|
||||||
if (!buffer_is_due || !consumer_is_ready) {
|
if (!buffer_is_due || !consumer_is_ready) {
|
||||||
LOG_DEBUG(Service_NVFlinger, "defer desire={} expect={}", desired_present,
|
LOG_DEBUG(Service_NVFlinger, "defer desire={} expect={}", desired_present,
|
||||||
expected_presenst_ns);
|
expected_present.count());
|
||||||
return Status::PresentLater;
|
return Status::PresentLater;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG(Service_NVFlinger, "accept desire={} expect={}", desired_present,
|
LOG_DEBUG(Service_NVFlinger, "accept desire={} expect={}", desired_present,
|
||||||
expected_presenst_ns);
|
expected_present.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto slot = front->slot;
|
const auto slot = front->slot;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -23,7 +24,7 @@ public:
|
||||||
explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_);
|
explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_);
|
||||||
~BufferQueueConsumer();
|
~BufferQueueConsumer();
|
||||||
|
|
||||||
Status AcquireBuffer(BufferItem* out_buffer, s64 expected_presenst_ns,
|
Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present,
|
||||||
u64 max_frame_number = 0);
|
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);
|
||||||
|
|
|
@ -52,14 +52,14 @@ void ConsumerBase::OnBuffersReleased() {
|
||||||
|
|
||||||
void ConsumerBase::OnSidebandStreamChanged() {}
|
void ConsumerBase::OnSidebandStreamChanged() {}
|
||||||
|
|
||||||
Status ConsumerBase::AcquireBufferLocked(BufferItem* item, u64 present_when_ns,
|
Status ConsumerBase::AcquireBufferLocked(BufferItem* item, std::chrono::nanoseconds present_when,
|
||||||
u64 max_frame_number) {
|
u64 max_frame_number) {
|
||||||
if (is_abandoned) {
|
if (is_abandoned) {
|
||||||
LOG_ERROR(Service_NVFlinger, "consumer is abandoned!");
|
LOG_ERROR(Service_NVFlinger, "consumer is abandoned!");
|
||||||
return Status::NoInit;
|
return Status::NoInit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status err = consumer->AcquireBuffer(item, present_when_ns, max_frame_number);
|
Status err = consumer->AcquireBuffer(item, present_when, max_frame_number);
|
||||||
if (err != Status::NoError) {
|
if (err != Status::NoError) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
@ -34,7 +35,8 @@ protected:
|
||||||
virtual void OnSidebandStreamChanged() override;
|
virtual void OnSidebandStreamChanged() override;
|
||||||
|
|
||||||
void FreeBufferLocked(s32 slot_index);
|
void FreeBufferLocked(s32 slot_index);
|
||||||
Status AcquireBufferLocked(BufferItem* item, u64 present_when_ns, u64 max_frame_number = 0);
|
Status AcquireBufferLocked(BufferItem* item, std::chrono::nanoseconds present_when,
|
||||||
|
u64 max_frame_number = 0);
|
||||||
Status ReleaseBufferLocked(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer);
|
Status ReleaseBufferLocked(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer);
|
||||||
bool StillTracking(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer);
|
bool StillTracking(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer);
|
||||||
Status AddReleaseFenceLocked(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer,
|
Status AddReleaseFenceLocked(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer,
|
||||||
|
|
|
@ -240,7 +240,7 @@ void NVFlinger::Compose() {
|
||||||
VI::Layer& layer = display.GetLayer(0);
|
VI::Layer& layer = display.GetLayer(0);
|
||||||
|
|
||||||
android::BufferItem buffer{};
|
android::BufferItem buffer{};
|
||||||
const auto status = layer.GetConsumer().AcquireBuffer(&buffer, 0, false);
|
const auto status = layer.GetConsumer().AcquireBuffer(&buffer, {}, false);
|
||||||
|
|
||||||
if (status != android::Status::NoError) {
|
if (status != android::Status::NoError) {
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in a new issue