nvflinger: Implement swap intervals

This commit is contained in:
Fernando Sahmkow 2019-06-04 16:10:07 -04:00 committed by FernandoS27
parent 772c86a260
commit ceb5f5079c
5 changed files with 21 additions and 8 deletions

View file

@ -63,7 +63,7 @@ const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const {
} }
void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
const Common::Rectangle<int>& crop_rect) { const Common::Rectangle<int>& crop_rect, u32 swap_interval) {
auto itr = std::find_if(queue.begin(), queue.end(), auto itr = std::find_if(queue.begin(), queue.end(),
[&](const Buffer& buffer) { return buffer.slot == slot; }); [&](const Buffer& buffer) { return buffer.slot == slot; });
ASSERT(itr != queue.end()); ASSERT(itr != queue.end());
@ -71,6 +71,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
itr->status = Buffer::Status::Queued; itr->status = Buffer::Status::Queued;
itr->transform = transform; itr->transform = transform;
itr->crop_rect = crop_rect; itr->crop_rect = crop_rect;
itr->swap_interval = swap_interval;
} }
std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {

View file

@ -68,13 +68,14 @@ public:
IGBPBuffer igbp_buffer; IGBPBuffer igbp_buffer;
BufferTransformFlags transform; BufferTransformFlags transform;
Common::Rectangle<int> crop_rect; Common::Rectangle<int> crop_rect;
u32 swap_interval;
}; };
void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer); void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer);
std::optional<u32> DequeueBuffer(u32 width, u32 height); std::optional<u32> DequeueBuffer(u32 width, u32 height);
const IGBPBuffer& RequestBuffer(u32 slot) const; const IGBPBuffer& RequestBuffer(u32 slot) const;
void QueueBuffer(u32 slot, BufferTransformFlags transform, void QueueBuffer(u32 slot, BufferTransformFlags transform,
const Common::Rectangle<int>& crop_rect); const Common::Rectangle<int>& crop_rect, u32 swap_interval);
std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer(); std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer();
void ReleaseBuffer(u32 slot); void ReleaseBuffer(u32 slot);
u32 Query(QueryType type); u32 Query(QueryType type);

View file

@ -37,15 +37,16 @@ NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_t
displays.emplace_back(4, "Null"); displays.emplace_back(4, "Null");
// Schedule the screen composition events // Schedule the screen composition events
const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks; //const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks;
composition_event = core_timing.RegisterEvent( composition_event = core_timing.RegisterEvent(
"ScreenComposition", [this, ticks](u64 userdata, s64 cycles_late) { "ScreenComposition", [this](u64 userdata, s64 cycles_late) {
Compose(); Compose();
this->core_timing.ScheduleEvent(ticks - cycles_late, composition_event); const auto ticks = GetNextTicks();
this->core_timing.ScheduleEvent(std::max(0LL,ticks - cycles_late), composition_event);
}); });
core_timing.ScheduleEvent(ticks, composition_event); core_timing.ScheduleEvent(frame_ticks, composition_event);
} }
NVFlinger::~NVFlinger() { NVFlinger::~NVFlinger() {
@ -206,8 +207,13 @@ void NVFlinger::Compose() {
igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride,
buffer->get().transform, buffer->get().crop_rect); buffer->get().transform, buffer->get().crop_rect);
swap_interval = buffer->get().swap_interval;
buffer_queue.ReleaseBuffer(buffer->get().slot); buffer_queue.ReleaseBuffer(buffer->get().slot);
} }
} }
s64 NVFlinger::GetNextTicks() {
return (Core::Timing::BASE_CLOCK_RATE * (1LL << swap_interval)) / 120;
}
} // namespace Service::NVFlinger } // namespace Service::NVFlinger

View file

@ -74,6 +74,8 @@ public:
/// finished. /// finished.
void Compose(); void Compose();
s64 GetNextTicks();
private: private:
/// Finds the display identified by the specified ID. /// Finds the display identified by the specified ID.
VI::Display* FindDisplay(u64 display_id); VI::Display* FindDisplay(u64 display_id);
@ -98,6 +100,8 @@ private:
/// layers. /// layers.
u32 next_buffer_queue_id = 1; u32 next_buffer_queue_id = 1;
u32 swap_interval = 1;
/// Event that handles screen composition. /// Event that handles screen composition.
Core::Timing::EventType* composition_event; Core::Timing::EventType* composition_event;

View file

@ -418,7 +418,8 @@ public:
s32_le scaling_mode; s32_le scaling_mode;
NVFlinger::BufferQueue::BufferTransformFlags transform; NVFlinger::BufferQueue::BufferTransformFlags transform;
u32_le sticky_transform; u32_le sticky_transform;
INSERT_PADDING_WORDS(2); INSERT_PADDING_WORDS(1);
u32_le swap_interval;
u32_le fence_is_valid; u32_le fence_is_valid;
std::array<Fence, 2> fences; std::array<Fence, 2> fences;
@ -582,7 +583,7 @@ private:
IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()}; IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()};
buffer_queue.QueueBuffer(request.data.slot, request.data.transform, buffer_queue.QueueBuffer(request.data.slot, request.data.transform,
request.data.GetCropRect()); request.data.GetCropRect(), request.data.swap_interval);
IGBPQueueBufferResponseParcel response{1280, 720}; IGBPQueueBufferResponseParcel response{1280, 720};
ctx.WriteBuffer(response.Serialize()); ctx.WriteBuffer(response.Serialize());