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 { namespace Service::KernelHelpers {
ServiceContext::ServiceContext(Core::System& system_, std::string name_) ServiceContext::ServiceContext(Core::System& system_, std::string name_)
: kernel(system_.Kernel()) { : m_system(system_), kernel(system_.Kernel()) {
if (process = Kernel::GetCurrentProcessPointer(kernel); process != nullptr) { if (process = Kernel::GetCurrentProcessPointer(kernel); process != nullptr) {
return; return;
} }

View File

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

View File

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

View File

@ -14,6 +14,14 @@
#include "core/hle/service/nvnflinger/buffer_queue_defs.h" #include "core/hle/service/nvnflinger/buffer_queue_defs.h"
#include "core/hle/service/nvnflinger/status.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 { namespace Service::android {
class BufferItem; class BufferItem;
@ -30,6 +38,7 @@ public:
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 Disconnect(); Status Disconnect();
Status GetReleasedBuffers(u64* out_slot_mask); 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, void Transact(u32 code, std::span<const u8> parcel_data, std::span<u8> parcel_reply,
u32 flags) override; u32 flags) override;

View File

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

View File

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

View File

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

View File

@ -51,26 +51,31 @@ static_assert(sizeof(QueueBufferInput) == 84, "QueueBufferInput has wrong size")
struct QueueBufferOutput final { struct QueueBufferOutput final {
QueueBufferOutput(); 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; *width_ = width;
*height_ = height; *height_ = height;
*transform_hint_ = transform_hint; *transform_hint_ = transform_hint;
*num_pending_buffers_ = num_pending_buffers; *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_; width = width_;
height = height_; height = height_;
transform_hint = transform_hint_; transform_hint = transform_hint_;
num_pending_buffers = num_pending_buffers_; num_pending_buffers = num_pending_buffers_;
frame_number = frame_number_;
} }
private: public:
u32 width{}; u32 width{};
u32 height{}; u32 height{};
u32 transform_hint{}; u32 transform_hint{};
u32 num_pending_buffers{}; 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 } // namespace Service::android

View File

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