summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp3
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h3
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp14
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h4
-rw-r--r--src/core/hle/service/vi/vi.cpp5
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
65void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, 65void 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
76std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { 77std::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
51NVFlinger::~NVFlinger() { 52NVFlinger::~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
215s64 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
77private: 79private:
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());