mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 1628137 - Switch to using WaitForVBlank for vsync on Windows r=jrmuizel
Differential Revision: https://phabricator.services.mozilla.com/D70463 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
8b5365a15b
commit
9051184fab
@ -170,6 +170,34 @@ nsTArray<DXGI_OUTPUT_DESC1> DeviceManagerDx::EnumerateOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
bool DeviceManagerDx::GetOutputFromMonitor(HMONITOR monitor,
|
||||
RefPtr<IDXGIOutput>* aOutOutput) {
|
||||
RefPtr<IDXGIAdapter> adapter = GetDXGIAdapter();
|
||||
|
||||
if (!adapter) {
|
||||
NS_WARNING("Failed to acquire a DXGI adapter for GetOutputFromMonitor.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (UINT i = 0;; ++i) {
|
||||
RefPtr<IDXGIOutput> output = nullptr;
|
||||
if (FAILED(adapter->EnumOutputs(i, getter_AddRefs(output)))) {
|
||||
break;
|
||||
}
|
||||
|
||||
DXGI_OUTPUT_DESC desc;
|
||||
if (FAILED(output->GetDesc(&desc))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (desc.Monitor == monitor) {
|
||||
*aOutOutput = output;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceManagerDx::CheckHardwareStretchingSupport() {
|
||||
RefPtr<IDXGIAdapter> adapter = GetDXGIAdapter();
|
||||
|
||||
|
@ -87,6 +87,10 @@ class DeviceManagerDx final {
|
||||
// Enumerate and return all outputs on the current adapter.
|
||||
nsTArray<DXGI_OUTPUT_DESC1> EnumerateOutputs();
|
||||
|
||||
// find the IDXGIOutput with a description.Monitor matching
|
||||
// 'monitor'; returns false if not found or some error occurred.
|
||||
bool GetOutputFromMonitor(HMONITOR monitor, RefPtr<IDXGIOutput>* aOutOutput);
|
||||
|
||||
// Check if the current adapter supports hardware stretching
|
||||
bool CheckHardwareStretchingSupport();
|
||||
|
||||
|
@ -1621,7 +1621,8 @@ class D3DVsyncSource final : public VsyncSource {
|
||||
D3DVsyncDisplay()
|
||||
: mPrevVsync(TimeStamp::Now()),
|
||||
mVsyncEnabledLock("D3DVsyncEnabledLock"),
|
||||
mVsyncEnabled(false) {
|
||||
mVsyncEnabled(false),
|
||||
mWaitVBlankMonitor(NULL) {
|
||||
mVsyncThread = new base::Thread("WindowsVsyncThread");
|
||||
MOZ_RELEASE_ASSERT(mVsyncThread->Start(),
|
||||
"GFX: Could not start Windows vsync thread");
|
||||
@ -1796,9 +1797,16 @@ class D3DVsyncSource final : public VsyncSource {
|
||||
return;
|
||||
}
|
||||
|
||||
// Using WaitForVBlank, the whole system dies because WaitForVBlank
|
||||
// only works if it's run on the same thread as the Present();
|
||||
HRESULT hr = DwmFlush();
|
||||
HRESULT hr = E_FAIL;
|
||||
if (StaticPrefs::gfx_vsync_use_waitforvblank()) {
|
||||
UpdateVBlankOutput();
|
||||
if (mWaitVBlankOutput) {
|
||||
hr = mWaitVBlankOutput->WaitForVBlank();
|
||||
}
|
||||
}
|
||||
if (!SUCCEEDED(hr)) {
|
||||
hr = DwmFlush();
|
||||
}
|
||||
if (!SUCCEEDED(hr)) {
|
||||
// DWMFlush isn't working, fallback to software vsync.
|
||||
ScheduleSoftwareVsync(TimeStamp::Now());
|
||||
@ -1846,11 +1854,35 @@ class D3DVsyncSource final : public VsyncSource {
|
||||
return mVsyncThread->thread_id() == PlatformThread::CurrentId();
|
||||
}
|
||||
|
||||
void UpdateVBlankOutput() {
|
||||
HMONITOR primary_monitor =
|
||||
MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY);
|
||||
if (primary_monitor == mWaitVBlankMonitor && mWaitVBlankOutput) {
|
||||
return;
|
||||
}
|
||||
|
||||
mWaitVBlankMonitor = primary_monitor;
|
||||
|
||||
RefPtr<IDXGIOutput> output = nullptr;
|
||||
if (DeviceManagerDx* dx = DeviceManagerDx::Get()) {
|
||||
if (dx->GetOutputFromMonitor(mWaitVBlankMonitor, &output)) {
|
||||
mWaitVBlankOutput = output;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// failed to convert a monitor to an output so keep trying
|
||||
mWaitVBlankOutput = nullptr;
|
||||
}
|
||||
|
||||
TimeStamp mPrevVsync;
|
||||
Monitor mVsyncEnabledLock;
|
||||
base::Thread* mVsyncThread;
|
||||
TimeDuration mVsyncRate;
|
||||
bool mVsyncEnabled;
|
||||
|
||||
HMONITOR mWaitVBlankMonitor;
|
||||
RefPtr<IDXGIOutput> mWaitVBlankOutput;
|
||||
}; // end d3dvsyncdisplay
|
||||
|
||||
D3DVsyncSource() { mPrimaryDisplay = new D3DVsyncDisplay(); }
|
||||
|
@ -3989,6 +3989,11 @@
|
||||
value: 10
|
||||
mirror: once
|
||||
|
||||
- name: gfx.vsync.use-waitforvblank
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# We expose two prefs: gfx.webrender.all and gfx.webrender.enabled.
|
||||
# The first enables WR+additional features, and the second just enables WR.
|
||||
# For developer convenience, building with --enable-webrender=true or just
|
||||
|
Loading…
Reference in New Issue
Block a user