diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 14 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 5 |
5 files changed, 21 insertions, 8 deletions
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 5731e815f..dca75c35e 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -63,7 +63,7 @@ const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const { | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, | 65 | void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, |
| 66 | const Common::Rectangle<int>& crop_rect) { | 66 | const Common::Rectangle<int>& crop_rect, u32 swap_interval) { |
| 67 | auto itr = std::find_if(queue.begin(), queue.end(), | 67 | auto itr = std::find_if(queue.begin(), queue.end(), |
| 68 | [&](const Buffer& buffer) { return buffer.slot == slot; }); | 68 | [&](const Buffer& buffer) { return buffer.slot == slot; }); |
| 69 | ASSERT(itr != queue.end()); | 69 | ASSERT(itr != queue.end()); |
| @@ -71,6 +71,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, | |||
| 71 | itr->status = Buffer::Status::Queued; | 71 | itr->status = Buffer::Status::Queued; |
| 72 | itr->transform = transform; | 72 | itr->transform = transform; |
| 73 | itr->crop_rect = crop_rect; | 73 | itr->crop_rect = crop_rect; |
| 74 | itr->swap_interval = swap_interval; | ||
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { | 77 | std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index e1ccb6171..139b98b9f 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h | |||
| @@ -68,13 +68,14 @@ public: | |||
| 68 | IGBPBuffer igbp_buffer; | 68 | IGBPBuffer igbp_buffer; |
| 69 | BufferTransformFlags transform; | 69 | BufferTransformFlags transform; |
| 70 | Common::Rectangle<int> crop_rect; | 70 | Common::Rectangle<int> crop_rect; |
| 71 | u32 swap_interval; | ||
| 71 | }; | 72 | }; |
| 72 | 73 | ||
| 73 | void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer); | 74 | void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer); |
| 74 | std::optional<u32> DequeueBuffer(u32 width, u32 height); | 75 | std::optional<u32> DequeueBuffer(u32 width, u32 height); |
| 75 | const IGBPBuffer& RequestBuffer(u32 slot) const; | 76 | const IGBPBuffer& RequestBuffer(u32 slot) const; |
| 76 | void QueueBuffer(u32 slot, BufferTransformFlags transform, | 77 | void QueueBuffer(u32 slot, BufferTransformFlags transform, |
| 77 | const Common::Rectangle<int>& crop_rect); | 78 | const Common::Rectangle<int>& crop_rect, u32 swap_interval); |
| 78 | std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer(); | 79 | std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer(); |
| 79 | void ReleaseBuffer(u32 slot); | 80 | void ReleaseBuffer(u32 slot); |
| 80 | u32 Query(QueryType type); | 81 | u32 Query(QueryType type); |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 3c5c53e24..6d83535e7 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -37,15 +37,16 @@ NVFlinger::NVFlinger(Core::Timing::CoreTiming& core_timing) : core_timing{core_t | |||
| 37 | displays.emplace_back(4, "Null"); | 37 | displays.emplace_back(4, "Null"); |
| 38 | 38 | ||
| 39 | // Schedule the screen composition events | 39 | // Schedule the screen composition events |
| 40 | const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks; | 40 | //const auto ticks = Settings::values.force_30fps_mode ? frame_ticks_30fps : frame_ticks; |
| 41 | 41 | ||
| 42 | composition_event = core_timing.RegisterEvent( | 42 | composition_event = core_timing.RegisterEvent( |
| 43 | "ScreenComposition", [this, ticks](u64 userdata, s64 cycles_late) { | 43 | "ScreenComposition", [this](u64 userdata, s64 cycles_late) { |
| 44 | Compose(); | 44 | Compose(); |
| 45 | this->core_timing.ScheduleEvent(ticks - cycles_late, composition_event); | 45 | const auto ticks = GetNextTicks(); |
| 46 | this->core_timing.ScheduleEvent(std::max(0LL,ticks - cycles_late), composition_event); | ||
| 46 | }); | 47 | }); |
| 47 | 48 | ||
| 48 | core_timing.ScheduleEvent(ticks, composition_event); | 49 | core_timing.ScheduleEvent(frame_ticks, composition_event); |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | NVFlinger::~NVFlinger() { | 52 | NVFlinger::~NVFlinger() { |
| @@ -206,8 +207,13 @@ void NVFlinger::Compose() { | |||
| 206 | igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, | 207 | igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, |
| 207 | buffer->get().transform, buffer->get().crop_rect); | 208 | buffer->get().transform, buffer->get().crop_rect); |
| 208 | 209 | ||
| 210 | swap_interval = buffer->get().swap_interval; | ||
| 209 | buffer_queue.ReleaseBuffer(buffer->get().slot); | 211 | buffer_queue.ReleaseBuffer(buffer->get().slot); |
| 210 | } | 212 | } |
| 211 | } | 213 | } |
| 212 | 214 | ||
| 215 | s64 NVFlinger::GetNextTicks() { | ||
| 216 | return (Core::Timing::BASE_CLOCK_RATE * (1LL << swap_interval)) / 120; | ||
| 217 | } | ||
| 218 | |||
| 213 | } // namespace Service::NVFlinger | 219 | } // namespace Service::NVFlinger |
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index c0a83fffb..86b94302c 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h | |||
| @@ -74,6 +74,8 @@ public: | |||
| 74 | /// finished. | 74 | /// finished. |
| 75 | void Compose(); | 75 | void Compose(); |
| 76 | 76 | ||
| 77 | s64 GetNextTicks(); | ||
| 78 | |||
| 77 | private: | 79 | private: |
| 78 | /// Finds the display identified by the specified ID. | 80 | /// Finds the display identified by the specified ID. |
| 79 | VI::Display* FindDisplay(u64 display_id); | 81 | VI::Display* FindDisplay(u64 display_id); |
| @@ -98,6 +100,8 @@ private: | |||
| 98 | /// layers. | 100 | /// layers. |
| 99 | u32 next_buffer_queue_id = 1; | 101 | u32 next_buffer_queue_id = 1; |
| 100 | 102 | ||
| 103 | u32 swap_interval = 1; | ||
| 104 | |||
| 101 | /// Event that handles screen composition. | 105 | /// Event that handles screen composition. |
| 102 | Core::Timing::EventType* composition_event; | 106 | Core::Timing::EventType* composition_event; |
| 103 | 107 | ||
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index f1fa6ccd1..55bd252c2 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -418,7 +418,8 @@ public: | |||
| 418 | s32_le scaling_mode; | 418 | s32_le scaling_mode; |
| 419 | NVFlinger::BufferQueue::BufferTransformFlags transform; | 419 | NVFlinger::BufferQueue::BufferTransformFlags transform; |
| 420 | u32_le sticky_transform; | 420 | u32_le sticky_transform; |
| 421 | INSERT_PADDING_WORDS(2); | 421 | INSERT_PADDING_WORDS(1); |
| 422 | u32_le swap_interval; | ||
| 422 | u32_le fence_is_valid; | 423 | u32_le fence_is_valid; |
| 423 | std::array<Fence, 2> fences; | 424 | std::array<Fence, 2> fences; |
| 424 | 425 | ||
| @@ -582,7 +583,7 @@ private: | |||
| 582 | IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()}; | 583 | IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()}; |
| 583 | 584 | ||
| 584 | buffer_queue.QueueBuffer(request.data.slot, request.data.transform, | 585 | buffer_queue.QueueBuffer(request.data.slot, request.data.transform, |
| 585 | request.data.GetCropRect()); | 586 | request.data.GetCropRect(), request.data.swap_interval); |
| 586 | 587 | ||
| 587 | IGBPQueueBufferResponseParcel response{1280, 720}; | 588 | IGBPQueueBufferResponseParcel response{1280, 720}; |
| 588 | ctx.WriteBuffer(response.Serialize()); | 589 | ctx.WriteBuffer(response.Serialize()); |