Просмотр исходного кода

NV: Give each display its own vsync event.

Subv 8 лет назад
Родитель
Сommit
d205dee0a6
2 измененных файлов с 29 добавлено и 12 удалено
  1. 17 8
      src/core/hle/service/vi/vi.cpp
  2. 12 4
      src/core/hle/service/vi/vi.h

+ 17 - 8
src/core/hle/service/vi/vi.cpp

@@ -599,6 +599,8 @@ void IApplicationDisplayService::GetDisplayVsyncEvent(Kernel::HLERequestContext&
     IPC::RequestParser rp{ctx};
     IPC::RequestParser rp{ctx};
     u64 display_id = rp.Pop<u64>();
     u64 display_id = rp.Pop<u64>();
 
 
+    auto vsync_event = nv_flinger->GetVsyncEvent(display_id);
+
     IPC::RequestBuilder rb = rp.MakeBuilder(2, 1, 0, 0);
     IPC::RequestBuilder rb = rp.MakeBuilder(2, 1, 0, 0);
     rb.Push(RESULT_SUCCESS);
     rb.Push(RESULT_SUCCESS);
     rb.PushCopyObjects(vsync_event);
     rb.PushCopyObjects(vsync_event);
@@ -618,8 +620,6 @@ IApplicationDisplayService::IApplicationDisplayService(std::shared_ptr<NVFlinger
         {5202, &IApplicationDisplayService::GetDisplayVsyncEvent, "GetDisplayVsyncEvent"},
         {5202, &IApplicationDisplayService::GetDisplayVsyncEvent, "GetDisplayVsyncEvent"},
     };
     };
     RegisterHandlers(functions);
     RegisterHandlers(functions);
-
-    vsync_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "Display VSync Event");
 }
 }
 
 
 void InstallInterfaces(SM::ServiceManager& service_manager) {
 void InstallInterfaces(SM::ServiceManager& service_manager) {
@@ -628,10 +628,10 @@ void InstallInterfaces(SM::ServiceManager& service_manager) {
 
 
 NVFlinger::NVFlinger() {
 NVFlinger::NVFlinger() {
     // Add the different displays to the list of displays.
     // Add the different displays to the list of displays.
-    Display default_{"Default", 0};
-    Display external{"External", 1};
-    Display edid{"Edid", 2};
-    Display internal{"Internal", 3};
+    Display default_{0, "Default"};
+    Display external{1, "External"};
+    Display edid{2, "Edid"};
+    Display internal{3, "Internal"};
 
 
     displays.emplace_back(default_);
     displays.emplace_back(default_);
     displays.emplace_back(external);
     displays.emplace_back(external);
@@ -667,11 +667,16 @@ u64 NVFlinger::CreateLayer(u64 display_id) {
 }
 }
 
 
 u32 NVFlinger::GetBufferQueueId(u64 display_id, u64 layer_id) {
 u32 NVFlinger::GetBufferQueueId(u64 display_id, u64 layer_id) {
-    auto& layer = GetLayer(display_id, layer_id);
+    const auto& layer = GetLayer(display_id, layer_id);
     return layer.buffer_queue->GetId();
     return layer.buffer_queue->GetId();
 }
 }
 
 
-std::shared_ptr<BufferQueue> NVFlinger::GetBufferQueue(u32 id) {
+Kernel::SharedPtr<Kernel::Event> NVFlinger::GetVsyncEvent(u64 display_id) {
+    const auto& display = GetDisplay(display_id);
+    return display.vsync_event;
+}
+
+std::shared_ptr<BufferQueue> NVFlinger::GetBufferQueue(u32 id) const {
     auto itr = std::find_if(buffer_queues.begin(), buffer_queues.end(),
     auto itr = std::find_if(buffer_queues.begin(), buffer_queues.end(),
                             [&](const auto& queue) { return queue->GetId() == id; });
                             [&](const auto& queue) { return queue->GetId() == id; });
 
 
@@ -745,5 +750,9 @@ void BufferQueue::QueueBuffer(u32 slot) {
 
 
 Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {}
 Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {}
 
 
+Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) {
+    vsync_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "Display VSync Event");
+}
+
 } // namespace VI
 } // namespace VI
 } // namespace Service
 } // namespace Service

+ 12 - 4
src/core/hle/service/vi/vi.h

@@ -39,7 +39,9 @@ public:
     const IGBPBuffer& RequestBuffer(u32 slot) const;
     const IGBPBuffer& RequestBuffer(u32 slot) const;
     void QueueBuffer(u32 slot);
     void QueueBuffer(u32 slot);
 
 
-    u32 GetId() const { return id; }
+    u32 GetId() const {
+        return id;
+    }
 
 
 private:
 private:
     u32 id;
     u32 id;
@@ -65,10 +67,14 @@ struct Layer {
 };
 };
 
 
 struct Display {
 struct Display {
-    std::string name;
+    Display(u64 id, std::string name);
+    ~Display() = default;
+
     u64 id;
     u64 id;
+    std::string name;
 
 
     std::vector<Layer> layers;
     std::vector<Layer> layers;
+    Kernel::SharedPtr<Kernel::Event> vsync_event;
 };
 };
 
 
 class NVFlinger {
 class NVFlinger {
@@ -85,8 +91,11 @@ public:
     /// Gets the buffer queue id of the specified layer in the specified display.
     /// Gets the buffer queue id of the specified layer in the specified display.
     u32 GetBufferQueueId(u64 display_id, u64 layer_id);
     u32 GetBufferQueueId(u64 display_id, u64 layer_id);
 
 
+    /// Gets the vsync event for the specified display.
+    Kernel::SharedPtr<Kernel::Event> GetVsyncEvent(u64 display_id);
+
     /// Obtains a buffer queue identified by the id.
     /// Obtains a buffer queue identified by the id.
-    std::shared_ptr<BufferQueue> GetBufferQueue(u32 id);
+    std::shared_ptr<BufferQueue> GetBufferQueue(u32 id) const;
 
 
 private:
 private:
     /// Returns the display identified by the specified id.
     /// Returns the display identified by the specified id.
@@ -119,7 +128,6 @@ private:
     void OpenLayer(Kernel::HLERequestContext& ctx);
     void OpenLayer(Kernel::HLERequestContext& ctx);
     void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx);
     void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx);
 
 
-    Kernel::SharedPtr<Kernel::Event> vsync_event;
     std::shared_ptr<NVFlinger> nv_flinger;
     std::shared_ptr<NVFlinger> nv_flinger;
 };
 };