Commit 0825e1d3 authored by Zhenyao Mo's avatar Zhenyao Mo Committed by Commit Bot

Only request a present duration if the system supports it.

BUG=711140
TEST=manual
R=sunnyps@chromium.org,rafael.cintron@microsoft.com

Change-Id: I407e1ff43b5788819e54acce6358b0ff4ed1bfd4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2399842Reviewed-by: default avatarRafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: default avatarSunny Sachanandani <sunnyps@chromium.org>
Commit-Queue: Zhenyao Mo <zmo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805600}
parent 1b954d76
......@@ -147,7 +147,6 @@ bool DirectCompositionChildSurfaceWin::ReleaseDrawTexture(bool will_discard) {
UINT interval =
first_swap_ || !vsync_enabled_ || use_swap_chain_tearing ? 0 : 1;
UINT flags = use_swap_chain_tearing ? DXGI_PRESENT_ALLOW_TEARING : 0;
flags |= DXGI_PRESENT_USE_DURATION;
bool force_full_damage =
ShouldForceDirectCompositionRootSurfaceFullDamage();
......@@ -406,8 +405,6 @@ bool DirectCompositionChildSurfaceWin::SetDrawRectangle(
DCHECK(SUCCEEDED(hr))
<< "SetColorSpace1 failed with error " << std::hex << hr;
}
SetSwapChainPresentDuration();
}
swap_rect_ = rectangle;
......@@ -532,23 +529,6 @@ bool DirectCompositionChildSurfaceWin::SetEnableDCLayers(bool enable) {
return true;
}
void DirectCompositionChildSurfaceWin::SetFrameRate(float frame_rate) {
frame_rate_ = frame_rate;
SetSwapChainPresentDuration();
}
void DirectCompositionChildSurfaceWin::SetSwapChainPresentDuration() {
if (!swap_chain_)
return;
Microsoft::WRL::ComPtr<IDXGISwapChainMedia> swap_chain_media;
if (SUCCEEDED(swap_chain_.As(&swap_chain_media))) {
UINT duration_100ns = FrameRateToPresentDuration(frame_rate_);
HRESULT hr = swap_chain_media->SetPresentDuration(duration_100ns);
if (FAILED(hr))
DLOG(ERROR) << "SetPresentDuration failed with error " << std::hex << hr;
}
}
gfx::VSyncProvider* DirectCompositionChildSurfaceWin::GetVSyncProvider() {
return vsync_thread_->vsync_provider();
}
......
......@@ -54,7 +54,6 @@ class GL_EXPORT DirectCompositionChildSurfaceWin : public GLSurfaceEGL,
const gfx::ColorSpace& color_space,
bool has_alpha) override;
bool SetEnableDCLayers(bool enable) override;
void SetFrameRate(float frame_rate) override;
gfx::VSyncProvider* GetVSyncProvider() override;
bool SupportsGpuVSync() const override;
void SetGpuVSyncEnabled(bool enabled) override;
......@@ -110,10 +109,6 @@ class GL_EXPORT DirectCompositionChildSurfaceWin : public GLSurfaceEGL,
// to it. Returns false if this fails.
bool ReleaseDrawTexture(bool will_discard);
// This is called when a new swap chain is created, or when a new frame rate
// is received.
void SetSwapChainPresentDuration();
gfx::Size size_ = gfx::Size(1, 1);
bool enable_dc_layers_ = false;
bool has_alpha_ = true;
......@@ -142,9 +137,6 @@ class GL_EXPORT DirectCompositionChildSurfaceWin : public GLSurfaceEGL,
Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain_;
Microsoft::WRL::ComPtr<ID3D11Texture2D> draw_texture_;
// Number of frames per second.
float frame_rate_ = 0.f;
const VSyncCallback vsync_callback_;
const bool use_angle_texture_offset_;
const size_t max_pending_frames_;
......
......@@ -743,8 +743,12 @@ bool DirectCompositionSurfaceWin::ScheduleDCLayer(
}
void DirectCompositionSurfaceWin::SetFrameRate(float frame_rate) {
// Only try to reduce vsync frequency through the video swap chain.
// This allows us to experiment UseSetPresentDuration optimization to
// fullscreen video overlays only and avoid compromising
// UsePreferredIntervalForVideo optimization where we skip compositing
// every other frame when fps <= half the vsync frame rate.
layer_tree_->SetFrameRate(frame_rate);
root_surface_->SetFrameRate(frame_rate);
}
bool DirectCompositionSurfaceWin::SetEnableDCLayers(bool enable) {
......
......@@ -1242,7 +1242,29 @@ void SwapChainPresenter::SetSwapChainPresentDuration() {
GetSwapChainMedia();
if (swap_chain_media) {
UINT duration_100ns = FrameRateToPresentDuration(frame_rate_);
HRESULT hr = swap_chain_media->SetPresentDuration(duration_100ns);
UINT requested_duration = 0u;
if (duration_100ns > 0) {
UINT smaller_duration = 0u, larger_duration = 0u;
HRESULT hr = swap_chain_media->CheckPresentDurationSupport(
duration_100ns, &smaller_duration, &larger_duration);
if (FAILED(hr)) {
DLOG(ERROR) << "CheckPresentDurationSupport failed with error "
<< std::hex << hr;
return;
}
constexpr UINT kDurationThreshold = 1000u;
// Smaller duration should be used to avoid frame loss. However, we want
// to take into consideration the larger duration is the same as the
// requested duration but was slightly different due to frame rate
// estimation errors.
if (larger_duration > 0 &&
larger_duration - duration_100ns < kDurationThreshold) {
requested_duration = larger_duration;
} else if (smaller_duration > 0) {
requested_duration = smaller_duration;
}
}
HRESULT hr = swap_chain_media->SetPresentDuration(requested_duration);
if (FAILED(hr)) {
DLOG(ERROR) << "SetPresentDuration failed with error " << std::hex << hr;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment