Updated queue/presentation time types and BufferInfo object for history

This commit is contained in:
Jarrod Norwell 2024-07-01 14:36:00 +08:00
parent 9fccf8f02a
commit a947dc8665
9 changed files with 88 additions and 19 deletions

View File

@ -14,7 +14,7 @@
namespace Service::KernelHelpers {
ServiceContext::ServiceContext(Core::System& system_, std::string name_)
: kernel(system_.Kernel()) {
: m_system(system_), kernel(system_.Kernel()) {
if (process = Kernel::GetCurrentProcessPointer(kernel); process != nullptr) {
return;
}

View File

@ -26,6 +26,8 @@ public:
void CloseEvent(Kernel::KEvent* event);
Core::System& m_system;
private:
Kernel::KernelCore& kernel;
Kernel::KProcess* process{};

View File

@ -11,6 +11,7 @@
#include "core/hle/service/nvnflinger/buffer_queue_core.h"
#include "core/hle/service/nvnflinger/parcel.h"
#include "core/hle/service/nvnflinger/producer_listener.h"
#include "core/hle/service/time/clock_types.h"
namespace Service::android {
@ -104,7 +105,7 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
const auto target_frame_number = slots[slot].frame_number;
for (int i = 0; i < core->history.size(); i++) {
if (core->history[i].frame_number = target_frame_number) {
if (core->history[i].frame_number == target_frame_number) {
core->history[i].state = BufferState::Acquired;
break;
}
@ -263,14 +264,28 @@ Status BufferQueueConsumer::GetReleasedBuffers(u64* out_slot_mask) {
return Status::NoError;
}
/* SetPresentTime
for (int i = 0; i < core->history.size(); i++) {
if (core->history[i].frame_number = target_frame_number) {
core->history[i].state == BufferState::Acquired;
break;
Status BufferQueueConsumer::SetPresentTime(s32 slot, u64 frame_number,
Time::Clock::TimeSpanType presentation_time) {
if (slot < 0 || slot >= slots.size())
return Status::BadValue;
std::scoped_lock lock{core->mutex};
if (slots[slot].frame_number != frame_number)
return Status::StaleBufferSlot;
if (slots[slot].presentation_time.nanoseconds == 0)
slots[slot].presentation_time = presentation_time;
for (int i = 0; i < core->history.size(); i++) {
if (core->history[i].frame_number == frame_number) {
core->history[i].presentation_time = presentation_time;
break;
}
}
return Status::NoError;
}
*/
void BufferQueueConsumer::Transact(u32 code, std::span<const u8> parcel_data,
std::span<u8> parcel_reply, u32 flags) {
@ -328,6 +343,15 @@ void BufferQueueConsumer::Transact(u32 code, std::span<const u8> parcel_data,
parcel_out.Write(slot_mask);
break;
}
case TransactionId::SetTransformHint: {
std::scoped_lock lock{core->mutex};
const u32 transform_hint = parcel_in.Read<u32>();
LOG_WARNING(Service_Nvnflinger, "Transact::SetTransformHint={}", transform_hint);
status = Status::NoError;
parcel_out.Write<u32>(transform_hint);
break;
}
default:
ASSERT_MSG(false, "called, code={} flags={}", code, flags);
break;

View File

@ -14,6 +14,14 @@
#include "core/hle/service/nvnflinger/buffer_queue_defs.h"
#include "core/hle/service/nvnflinger/status.h"
namespace Service {
namespace Time {
namespace Clock {
struct TimeSpanType;
} // namespace Clock
} // namespace Time
} // namespace Service
namespace Service::android {
class BufferItem;
@ -30,6 +38,7 @@ public:
Status Connect(std::shared_ptr<IConsumerListener> consumer_listener, bool controlled_by_app);
Status Disconnect();
Status GetReleasedBuffers(u64* out_slot_mask);
Status SetPresentTime(s32 slot, u64 frame_number, Time::Clock::TimeSpanType presentation_time);
void Transact(u32 code, std::span<const u8> parcel_data, std::span<u8> parcel_reply,
u32 flags) override;

View File

@ -18,6 +18,7 @@
#include "core/hle/service/nvnflinger/pixel_format.h"
#include "core/hle/service/nvnflinger/status.h"
#include "core/hle/service/nvnflinger/window.h"
#include "core/hle/service/time/clock_types.h"
namespace Service::android {
@ -76,7 +77,7 @@ private:
class BufferInfo final {
public:
u64 frame_number{};
s64 queue_time{}, presentation_time{};
Time::Clock::TimeSpanType queue_time, presentation_time;
BufferState state{BufferState::Free};
};

View File

@ -6,6 +6,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core_timing.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/kernel.h"
@ -16,6 +17,7 @@
#include "core/hle/service/nvnflinger/parcel.h"
#include "core/hle/service/nvnflinger/ui/graphic_buffer.h"
#include "core/hle/service/nvnflinger/window.h"
#include "core/hle/service/time/clock_types.h"
namespace Service::android {
@ -278,6 +280,9 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool
return_flags |= Status::BufferNeedsReallocation;
}
slots[found].queue_time = Time::Clock::TimeSpanType::FromSeconds(0);
slots[found].presentation_time = Time::Clock::TimeSpanType::FromSeconds(0);
*out_fence = slots[found].fence;
slots[found].fence = Fence::NoFence();
}
@ -508,12 +513,17 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
return Status::BadValue;
}
auto& ctx = service_context;
auto& system = ctx.m_system;
slots[slot].fence = fence;
slots[slot].buffer_state = BufferState::Queued;
++core->frame_counter;
slots[slot].frame_number = core->frame_counter;
slots[slot].queue_time = 0; // this is not the true value
slots[slot].presentation_time = 0; // doesn't need to be set afaik but do it anyway
slots[slot].queue_time = Time::Clock::TimeSpanType::FromTicks<Core::Hardware::CNTFREQ>(
system.CoreTiming().GetClockTicks()); // this is not the true value
slots[slot].presentation_time = Time::Clock::TimeSpanType::FromSeconds(
0); // doesn't need to be set afaik but do it anyway
item.acquire_called = slots[slot].acquire_called;
item.graphic_buffer = slots[slot].graphic_buffer;
@ -569,7 +579,12 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
core->buffer_has_been_queued = true;
core->SignalDequeueCondition();
output->Inflate(core->default_width, core->default_height, core->transform_hint,
static_cast<u32>(core->queue.size()));
static_cast<u32>(core->queue.size()), core->frame_counter);
if ((sticky_transform & 8) != 0) {
output->transform_hint |= (u32)NativeWindowTransform::ReturnFrameNumber;
output->frame_number = slots[slot].frame_number;
}
// Take a ticket for the callback functions
callback_ticket = next_callback_ticket++;
@ -670,7 +685,7 @@ Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) {
return Status::BadValue;
}
LOG_DEBUG(Service_Nvnflinger, "what = {}, value = {}", what, value);
LOG_WARNING(Service_Nvnflinger, "what = {}, value = {}", what, value);
*out_value = static_cast<s32>(value);
@ -714,7 +729,7 @@ Status BufferQueueProducer::Connect(const std::shared_ptr<IProducerListener>& li
case NativeWindowApi::Camera:
core->connected_api = api;
output->Inflate(core->default_width, core->default_height, core->transform_hint,
static_cast<u32>(core->queue.size()));
static_cast<u32>(core->queue.size()), core->frame_counter);
core->connected_producer_listener = listener;
break;
default:
@ -849,7 +864,12 @@ void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
status = Connect(listener, api, producer_controlled_by_app, &output);
LOG_WARNING(Service_Nvnflinger, "Connect, output.frame_number={}, output.transform_hint={}",
output.frame_number, output.transform_hint);
parcel_out.Write(output);
if (output.transform_hint & (u32)NativeWindowTransform::ReturnFrameNumber)
parcel_out.Write<u64>(output.frame_number);
break;
}
case TransactionId::SetPreallocatedBuffer: {
@ -892,8 +912,13 @@ void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
QueueBufferOutput output;
status = QueueBuffer(slot, input, &output);
LOG_WARNING(Service_Nvnflinger,
"QueueBuffer, output.frame_number={}, output.transform_hint={}",
output.frame_number, output.transform_hint);
parcel_out.Write(output);
if (output.transform_hint & (u32)NativeWindowTransform::ReturnFrameNumber)
parcel_out.Write<u64>(output.frame_number);
break;
}
case TransactionId::Query: {
@ -948,6 +973,7 @@ void BufferQueueProducer::Transact(u32 code, std::span<const u8> parcel_data,
pos--;
}
parcel_out.Write<s32>(buffer_history_count);
parcel_out.WriteFlattenedObject<BufferQueueCore::BufferInfo>(info);
status = Status::NoError;

View File

@ -10,6 +10,7 @@
#include "common/common_types.h"
#include "core/hle/service/nvnflinger/ui/fence.h"
#include "core/hle/service/time/clock_types.h"
namespace Service::android {
@ -35,7 +36,7 @@ struct BufferSlot final {
bool attached_by_consumer{};
bool is_preallocated{};
s64 queue_time{}, presentation_time{};
Time::Clock::TimeSpanType queue_time, presentation_time;
};
} // namespace Service::android

View File

@ -51,26 +51,31 @@ static_assert(sizeof(QueueBufferInput) == 84, "QueueBufferInput has wrong size")
struct QueueBufferOutput final {
QueueBufferOutput();
void Deflate(u32* width_, u32* height_, u32* transform_hint_, u32* num_pending_buffers_) const {
void Deflate(u32* width_, u32* height_, u32* transform_hint_, u32* num_pending_buffers_,
u64* frame_number_) const {
*width_ = width;
*height_ = height;
*transform_hint_ = transform_hint;
*num_pending_buffers_ = num_pending_buffers;
*frame_number_ = frame_number;
}
void Inflate(u32 width_, u32 height_, u32 transform_hint_, u32 num_pending_buffers_) {
void Inflate(u32 width_, u32 height_, u32 transform_hint_, u32 num_pending_buffers_,
u64 frame_number_) {
width = width_;
height = height_;
transform_hint = transform_hint_;
num_pending_buffers = num_pending_buffers_;
frame_number = frame_number_;
}
private:
public:
u32 width{};
u32 height{};
u32 transform_hint{};
u32 num_pending_buffers{};
u64 frame_number{};
};
static_assert(sizeof(QueueBufferOutput) == 16, "QueueBufferOutput has wrong size");
static_assert(sizeof(QueueBufferOutput) == 24, "QueueBufferOutput has wrong size");
} // namespace Service::android

View File

@ -48,6 +48,7 @@ enum class NativeWindowScalingMode : s32 {
enum class NativeWindowTransform : u32 {
None = 0x0,
InverseDisplay = 0x08,
ReturnFrameNumber = 0x20
};
DECLARE_ENUM_FLAG_OPERATORS(NativeWindowTransform);