diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index afe44efc7f8d..1cb4433da849 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -1252,7 +1252,7 @@ void CompositorD3D11::EndFrame() { // Block until the previous frame's work has been completed. if (mQuery) { BOOL result; - WaitForGPUQuery(mDevice, mContext, mQuery, &result); + WaitForFrameGPUQuery(mDevice, mContext, mQuery, &result); } // Store the query for this frame so we can flush it next time. mQuery = query; diff --git a/gfx/layers/d3d11/HelpersD3D11.h b/gfx/layers/d3d11/HelpersD3D11.h index c4b4dcaf6ee4..82dd716a52e9 100644 --- a/gfx/layers/d3d11/HelpersD3D11.h +++ b/gfx/layers/d3d11/HelpersD3D11.h @@ -8,6 +8,7 @@ #define mozilla_gfx_layers_d3d11_HelpersD3D11_h #include +#include "mozilla/Telemetry.h" #include "mozilla/TimeStamp.h" namespace mozilla { @@ -30,6 +31,25 @@ static inline bool WaitForGPUQuery(ID3D11Device* aDevice, return true; } +static inline bool WaitForFrameGPUQuery(ID3D11Device* aDevice, + ID3D11DeviceContext* aContext, + ID3D11Query* aQuery, bool* aOut) { + TimeStamp start = TimeStamp::Now(); + bool success = true; + while (aContext->GetData(aQuery, aOut, sizeof(*aOut), 0) != S_OK) { + if (aDevice->GetDeviceRemovedReason() != S_OK) { + return false; + } + if (TimeStamp::Now() - start > TimeDuration::FromSeconds(2)) { + success = false; + break; + } + Sleep(0); + } + Telemetry::AccumulateTimeDelta(Telemetry::GPU_WAIT_TIME_MS, start); + return success; +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/d3d11/MLGDeviceD3D11.cpp b/gfx/layers/d3d11/MLGDeviceD3D11.cpp index 52352019b284..aa1265d67fa4 100644 --- a/gfx/layers/d3d11/MLGDeviceD3D11.cpp +++ b/gfx/layers/d3d11/MLGDeviceD3D11.cpp @@ -1786,7 +1786,7 @@ void MLGDeviceD3D11::InsertPresentWaitQuery() { void MLGDeviceD3D11::WaitForPreviousPresentQuery() { if (mWaitForPresentQuery) { BOOL result; - WaitForGPUQuery(mDevice, mCtx, mWaitForPresentQuery, &result); + WaitForFrameGPUQuery(mDevice, mCtx, mWaitForPresentQuery, &result); } mWaitForPresentQuery = mNextWaitForPresentQuery.forget(); } diff --git a/gfx/webrender_bindings/RenderCompositorANGLE.cpp b/gfx/webrender_bindings/RenderCompositorANGLE.cpp index 84d1672efe7c..d9f0cb92a8e7 100644 --- a/gfx/webrender_bindings/RenderCompositorANGLE.cpp +++ b/gfx/webrender_bindings/RenderCompositorANGLE.cpp @@ -510,7 +510,7 @@ void RenderCompositorANGLE::WaitForPreviousPresentQuery() { while (mWaitForPresentQueries.size() >= waitLatency) { RefPtr& query = mWaitForPresentQueries.front(); BOOL result; - layers::WaitForGPUQuery(mDevice, mCtx, query, &result); + layers::WaitForFrameGPUQuery(mDevice, mCtx, query, &result); // Recycle query for later use. mRecycledQuery = query; diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 6369427c5b28..f677578a2ee8 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -13232,6 +13232,17 @@ "n_buckets": 10, "description": "Percentages of times for phases in a normal content paint relative to the time spent in the entire normal paint. (\"dl\" = Display list, \"flb\" = Frame layer builder, \"fr\" = Flush rasterization, \"r\" = Rasterization)" }, + "GPU_WAIT_TIME_MS": { + "record_in_processes": ["main", "gpu"], + "alert_emails": ["gfx-telemetry-alerts@mozilla.com", "jmuizelaar@mozilla.com"], + "bug_numbers": [1524090], + "expires_in_version": "82", + "releaseChannelCollection": "opt-out", + "kind": "exponential", + "high": 5000, + "n_buckets": 50, + "description": "The number of milliseconds we spend waiting for the GPU" + }, "NARRATE_CONTENT_BY_LANGUAGE_2": { "record_in_processes": ["main", "content"], "alert_emails": ["eisaacson@mozilla.com"],