diff options
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 24 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.h | 9 |
2 files changed, 32 insertions, 1 deletions
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 4c9df099e..fab7a12e4 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/alignment.h" | 5 | #include "common/alignment.h" |
| 6 | #include "core/core_timing.h" | ||
| 6 | #include "core/hle/ipc_helpers.h" | 7 | #include "core/hle/ipc_helpers.h" |
| 7 | #include "core/hle/service/vi/vi.h" | 8 | #include "core/hle/service/vi/vi.h" |
| 8 | #include "core/hle/service/vi/vi_m.h" | 9 | #include "core/hle/service/vi/vi_m.h" |
| @@ -10,6 +11,9 @@ | |||
| 10 | namespace Service { | 11 | namespace Service { |
| 11 | namespace VI { | 12 | namespace VI { |
| 12 | 13 | ||
| 14 | constexpr size_t SCREEN_REFRESH_RATE = 60; | ||
| 15 | constexpr u64 frame_ticks = static_cast<u64>(BASE_CLOCK_RATE / SCREEN_REFRESH_RATE); | ||
| 16 | |||
| 13 | class Parcel { | 17 | class Parcel { |
| 14 | public: | 18 | public: |
| 15 | // This default size was chosen arbitrarily. | 19 | // This default size was chosen arbitrarily. |
| @@ -637,6 +641,19 @@ NVFlinger::NVFlinger() { | |||
| 637 | displays.emplace_back(external); | 641 | displays.emplace_back(external); |
| 638 | displays.emplace_back(edid); | 642 | displays.emplace_back(edid); |
| 639 | displays.emplace_back(internal); | 643 | displays.emplace_back(internal); |
| 644 | |||
| 645 | // Schedule the screen composition events | ||
| 646 | composition_event = | ||
| 647 | CoreTiming::RegisterEvent("ScreenCompositioin", [this](u64 userdata, int cycles_late) { | ||
| 648 | Compose(); | ||
| 649 | CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event); | ||
| 650 | }); | ||
| 651 | |||
| 652 | CoreTiming::ScheduleEvent(frame_ticks, composition_event); | ||
| 653 | } | ||
| 654 | |||
| 655 | NVFlinger::~NVFlinger() { | ||
| 656 | CoreTiming::UnscheduleEvent(composition_event, 0); | ||
| 640 | } | 657 | } |
| 641 | 658 | ||
| 642 | u64 NVFlinger::OpenDisplay(const std::string& name) { | 659 | u64 NVFlinger::OpenDisplay(const std::string& name) { |
| @@ -702,6 +719,13 @@ Layer& NVFlinger::GetLayer(u64 display_id, u64 layer_id) { | |||
| 702 | return *itr; | 719 | return *itr; |
| 703 | } | 720 | } |
| 704 | 721 | ||
| 722 | void NVFlinger::Compose() { | ||
| 723 | for (auto& display : displays) { | ||
| 724 | // TODO(Subv): Gather the surfaces and forward them to the GPU for drawing. | ||
| 725 | display.vsync_event->Signal(); | ||
| 726 | } | ||
| 727 | } | ||
| 728 | |||
| 705 | BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {} | 729 | BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {} |
| 706 | 730 | ||
| 707 | void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { | 731 | void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { |
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h index 029bd6831..1bd8f7472 100644 --- a/src/core/hle/service/vi/vi.h +++ b/src/core/hle/service/vi/vi.h | |||
| @@ -80,7 +80,7 @@ struct Display { | |||
| 80 | class NVFlinger { | 80 | class NVFlinger { |
| 81 | public: | 81 | public: |
| 82 | NVFlinger(); | 82 | NVFlinger(); |
| 83 | ~NVFlinger() = default; | 83 | ~NVFlinger(); |
| 84 | 84 | ||
| 85 | /// Opens the specified display and returns the id. | 85 | /// Opens the specified display and returns the id. |
| 86 | u64 OpenDisplay(const std::string& name); | 86 | u64 OpenDisplay(const std::string& name); |
| @@ -97,6 +97,10 @@ public: | |||
| 97 | /// Obtains a buffer queue identified by the id. | 97 | /// Obtains a buffer queue identified by the id. |
| 98 | std::shared_ptr<BufferQueue> GetBufferQueue(u32 id) const; | 98 | std::shared_ptr<BufferQueue> GetBufferQueue(u32 id) const; |
| 99 | 99 | ||
| 100 | /// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when | ||
| 101 | /// finished. | ||
| 102 | void Compose(); | ||
| 103 | |||
| 100 | private: | 104 | private: |
| 101 | /// Returns the display identified by the specified id. | 105 | /// Returns the display identified by the specified id. |
| 102 | Display& GetDisplay(u64 display_id); | 106 | Display& GetDisplay(u64 display_id); |
| @@ -112,6 +116,9 @@ private: | |||
| 112 | /// Id to use for the next buffer queue that is created, this counter is shared among all | 116 | /// Id to use for the next buffer queue that is created, this counter is shared among all |
| 113 | /// layers. | 117 | /// layers. |
| 114 | u32 next_buffer_queue_id = 1; | 118 | u32 next_buffer_queue_id = 1; |
| 119 | |||
| 120 | /// CoreTiming event that handles screen composition. | ||
| 121 | int composition_event; | ||
| 115 | }; | 122 | }; |
| 116 | 123 | ||
| 117 | class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> { | 124 | class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> { |