NV: Signal all display's vsync event 60 times per second.
This commit is contained in:
parent
d205dee0a6
commit
404149e475
2 changed files with 32 additions and 1 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
Loading…
Reference in a new issue