NV: Signal all display's vsync event 60 times per second.

This commit is contained in:
Subv 2018-01-08 19:12:28 -05:00 committed by bunnei
parent d205dee0a6
commit 404149e475
2 changed files with 32 additions and 1 deletions

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "common/alignment.h" #include "common/alignment.h"
#include "core/core_timing.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi.h"
#include "core/hle/service/vi/vi_m.h" #include "core/hle/service/vi/vi_m.h"
@ -10,6 +11,9 @@
namespace Service { namespace Service {
namespace VI { namespace VI {
constexpr size_t SCREEN_REFRESH_RATE = 60;
constexpr u64 frame_ticks = static_cast<u64>(BASE_CLOCK_RATE / SCREEN_REFRESH_RATE);
class Parcel { class Parcel {
public: public:
// This default size was chosen arbitrarily. // This default size was chosen arbitrarily.
@ -637,6 +641,19 @@ NVFlinger::NVFlinger() {
displays.emplace_back(external); displays.emplace_back(external);
displays.emplace_back(edid); displays.emplace_back(edid);
displays.emplace_back(internal); 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) { u64 NVFlinger::OpenDisplay(const std::string& name) {
@ -702,6 +719,13 @@ Layer& NVFlinger::GetLayer(u64 display_id, u64 layer_id) {
return *itr; 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) {} BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {}
void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) { void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) {

View file

@ -80,7 +80,7 @@ struct Display {
class NVFlinger { class NVFlinger {
public: public:
NVFlinger(); NVFlinger();
~NVFlinger() = default; ~NVFlinger();
/// Opens the specified display and returns the id. /// Opens the specified display and returns the id.
u64 OpenDisplay(const std::string& name); u64 OpenDisplay(const std::string& name);
@ -97,6 +97,10 @@ public:
/// Obtains a buffer queue identified by the id. /// Obtains a buffer queue identified by the id.
std::shared_ptr<BufferQueue> GetBufferQueue(u32 id) const; 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: private:
/// Returns the display identified by the specified id. /// Returns the display identified by the specified id.
Display& GetDisplay(u64 display_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 /// Id to use for the next buffer queue that is created, this counter is shared among all
/// layers. /// layers.
u32 next_buffer_queue_id = 1; u32 next_buffer_queue_id = 1;
/// CoreTiming event that handles screen composition.
int composition_event;
}; };
class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> { class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> {