Updated queue/presentation time types and BufferInfo object for history
This commit is contained in:
parent
9fccf8f02a
commit
a947dc8665
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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{};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue