diff options
| author | Subv <subv2112@gmail.com> | 2018-01-08 19:12:28 -0500 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2018-01-10 23:28:22 -0500 | 
| commit | 404149e4751b986b4a9bf895434862236d162fd8 (patch) | |
| tree | bed2b206c777c90dda9d3b2b3665360fb39bd170 | |
| parent | d205dee0a62c1310b6119175ef4f1963202f8a8a (diff) | |
NV: Signal all display's vsync event 60 times per second.
| -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 @@  // Refer to the license.txt file included.  #include "common/alignment.h" +#include "core/core_timing.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/vi/vi.h"  #include "core/hle/service/vi/vi_m.h" @@ -10,6 +11,9 @@  namespace Service {  namespace VI { +constexpr size_t SCREEN_REFRESH_RATE = 60; +constexpr u64 frame_ticks = static_cast<u64>(BASE_CLOCK_RATE / SCREEN_REFRESH_RATE); +  class Parcel {  public:      // This default size was chosen arbitrarily. @@ -637,6 +641,19 @@ NVFlinger::NVFlinger() {      displays.emplace_back(external);      displays.emplace_back(edid);      displays.emplace_back(internal); + +    // Schedule the screen composition events +    composition_event = +        CoreTiming::RegisterEvent("ScreenCompositioin", [this](u64 userdata, int cycles_late) { +            Compose(); +            CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event); +        }); + +    CoreTiming::ScheduleEvent(frame_ticks, composition_event); +} + +NVFlinger::~NVFlinger() { +    CoreTiming::UnscheduleEvent(composition_event, 0);  }  u64 NVFlinger::OpenDisplay(const std::string& name) { @@ -702,6 +719,13 @@ Layer& NVFlinger::GetLayer(u64 display_id, u64 layer_id) {      return *itr;  } +void NVFlinger::Compose() { +    for (auto& display : displays) { +        // TODO(Subv): Gather the surfaces and forward them to the GPU for drawing. +        display.vsync_event->Signal(); +    } +} +  BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {}  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 {  class NVFlinger {  public:      NVFlinger(); -    ~NVFlinger() = default; +    ~NVFlinger();      /// Opens the specified display and returns the id.      u64 OpenDisplay(const std::string& name); @@ -97,6 +97,10 @@ public:      /// Obtains a buffer queue identified by the id.      std::shared_ptr<BufferQueue> GetBufferQueue(u32 id) const; +    /// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when +    /// finished. +    void Compose(); +  private:      /// Returns the display identified by the specified id.      Display& GetDisplay(u64 display_id); @@ -112,6 +116,9 @@ private:      /// Id to use for the next buffer queue that is created, this counter is shared among all      /// layers.      u32 next_buffer_queue_id = 1; + +    /// CoreTiming event that handles screen composition. +    int composition_event;  };  class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> {  | 
