From c28b3ba4ed3156d8782484e542c25600615247b5 Mon Sep 17 00:00:00 2001 From: sotaro Date: Mon, 27 Feb 2023 05:29:24 +0000 Subject: [PATCH] Bug 1818685 - Disable video overlay if mVideoSwapChain->Present() is very slow on Windows r=gfx-reviewers,lsalzman There were cases that mVideoSwapChain->Present() took long time. It caused low fps and stuttering and lots of dropped frames. When it happens, disabling video overlay could address the problem. Differential Revision: https://phabricator.services.mozilla.com/D171039 --- gfx/webrender_bindings/DCLayerTree.cpp | 28 ++++++++++++++++++++++-- gfx/webrender_bindings/DCLayerTree.h | 1 + modules/libpref/init/StaticPrefList.yaml | 4 ++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/gfx/webrender_bindings/DCLayerTree.cpp b/gfx/webrender_bindings/DCLayerTree.cpp index 8d192ea09162..713fecdc18ca 100644 --- a/gfx/webrender_bindings/DCLayerTree.cpp +++ b/gfx/webrender_bindings/DCLayerTree.cpp @@ -1099,13 +1099,37 @@ void DCSurfaceVideo::PresentVideo() { return; } - HRESULT hr; - hr = mVideoSwapChain->Present(0, 0); + auto start = TimeStamp::Now(); + HRESULT hr = mVideoSwapChain->Present(0, 0); + auto end = TimeStamp::Now(); + if (FAILED(hr) && hr != DXGI_STATUS_OCCLUDED) { gfxCriticalNoteOnce << "video Present failed: " << gfx::hexa(hr); } mPrevTexture = mRenderTextureHost; + + // Disable video overlay if mVideoSwapChain->Present() is too slow. It drops + // fps. + + if (!StaticPrefs::gfx_webrender_dcomp_video_check_slow_present()) { + return; + } + + const auto maxWaitDurationMs = 2.0; + const auto maxSlowPresentCount = 5; + const auto duration = (end - start).ToMilliseconds(); + + if (duration > maxWaitDurationMs) { + mSlowPresentCount++; + } else { + mSlowPresentCount = 0; + } + + if (mSlowPresentCount > maxSlowPresentCount) { + gfxCriticalNoteOnce << "Video swapchain present is slow"; + RenderThread::Get()->HandleWebRenderError(WebRenderError::VIDEO_OVERLAY); + } } DXGI_FORMAT DCSurfaceVideo::GetSwapChainFormat() { diff --git a/gfx/webrender_bindings/DCLayerTree.h b/gfx/webrender_bindings/DCLayerTree.h index 25076444a967..402ffdd46487 100644 --- a/gfx/webrender_bindings/DCLayerTree.h +++ b/gfx/webrender_bindings/DCLayerTree.h @@ -353,6 +353,7 @@ class DCSurfaceVideo : public DCSurface { bool mFailedYuvSwapChain = false; RefPtr mRenderTextureHost; RefPtr mPrevTexture; + int mSlowPresentCount = 0; }; /** diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 08358b8748d6..2849daf90139 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -6528,6 +6528,10 @@ type: bool value: @IS_EARLY_BETA_OR_EARLIER@ mirror: once +- name: gfx.webrender.dcomp-video-check-slow-present + type: RelaxedAtomicBool + value: true + mirror: always - name: gfx.video.convert-i420-to-nv12.force-enabled type: bool value: false