Commit b8a68ab6 authored by Sunny Sachanandani's avatar Sunny Sachanandani Committed by Commit Bot

gpu: Feature flags for dcomp triple buffering

Add separate feature flags for video and main dcomp swap chains.

Bug: 1117318
Change-Id: Ic02400c56dc831dadf1cf43c4b948cea806dd5f9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2533836
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826675}
parent b8fc6bbd
......@@ -115,12 +115,14 @@ SkiaOutputDeviceGL::SkiaOutputDeviceGL(
capabilities_.output_surface_origin = gl_surface_->GetOrigin();
capabilities_.supports_post_sub_buffer = gl_surface_->SupportsPostSubBuffer();
#if defined(OS_WIN)
if (gl_surface_->SupportsDCLayers() &&
gl::ShouldForceDirectCompositionRootSurfaceFullDamage()) {
if (gl_surface_->SupportsDCLayers()) {
// We need to set this bit to allow viz to track the previous damage rect
// of a backbuffer in a multiple backbuffer system, so backbuffers always
// have valid pixels, even outside the current damage rect.
capabilities_.preserve_buffer_content = true;
capabilities_.preserve_buffer_content =
gl::ShouldForceDirectCompositionRootSurfaceFullDamage();
capabilities_.number_of_buffers =
gl::DirectCompositionRootSurfaceBufferCount();
}
#endif // OS_WIN
if (feature_info->workarounds()
......
......@@ -383,7 +383,7 @@ bool DirectCompositionChildSurfaceWin::SetDrawRectangle(
desc.Format = dxgi_format;
desc.Stereo = FALSE;
desc.SampleDesc.Count = 1;
desc.BufferCount = 2;
desc.BufferCount = gl::DirectCompositionRootSurfaceBufferCount();
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.Scaling = DXGI_SCALING_STRETCH;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
......@@ -512,11 +512,12 @@ bool DirectCompositionChildSurfaceWin::Resize(
// ResizeBuffers can't change alpha blending mode.
if (swap_chain_ && resize_only) {
UINT buffer_count = gl::DirectCompositionRootSurfaceBufferCount();
DXGI_FORMAT format = gfx::ColorSpaceWin::GetDXGIFormat(color_space_);
UINT flags = DirectCompositionSurfaceWin::AllowTearing()
? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING
: 0;
HRESULT hr = swap_chain_->ResizeBuffers(2 /* BufferCount */, size.width(),
HRESULT hr = swap_chain_->ResizeBuffers(buffer_count, size.width(),
size.height(), format, flags);
UMA_HISTOGRAM_BOOLEAN("GPU.DirectComposition.SwapChainResizeResult",
SUCCEEDED(hr));
......
......@@ -12,6 +12,7 @@
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/win/scoped_gdi_object.h"
#include "base/win/scoped_hdc.h"
......@@ -28,6 +29,7 @@
#include "ui/gl/gl_image_d3d.h"
#include "ui/gl/gl_image_dxgi.h"
#include "ui/gl/gl_image_ref_counted_memory.h"
#include "ui/gl/gl_switches.h"
#include "ui/gl/gl_version_info.h"
#include "ui/gl/init/gl_factory.h"
#include "ui/platform_window/platform_window_delegate.h"
......@@ -1329,5 +1331,93 @@ TEST_F(DirectCompositionPixelTest, RootSurfaceDrawOffset) {
}
}
void RunBufferCountTest(scoped_refptr<DirectCompositionSurfaceWin> surface,
UINT buffer_count,
bool for_video) {
if (!surface)
return;
if (for_video) {
DirectCompositionSurfaceWin::SetScaledOverlaysSupportedForTesting(true);
EXPECT_TRUE(surface->SetEnableDCLayers(true));
} else {
EXPECT_TRUE(surface->SetEnableDCLayers(false));
}
constexpr gfx::Size window_size(100, 100);
EXPECT_TRUE(surface->Resize(window_size, 1.0, gfx::ColorSpace(), true));
EXPECT_TRUE(surface->SetDrawRectangle(gfx::Rect(window_size)));
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
constexpr gfx::Size texture_size(50, 50);
if (for_video) {
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
QueryD3D11DeviceObjectFromANGLE();
ASSERT_TRUE(d3d11_device);
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture =
CreateNV12Texture(d3d11_device, texture_size, /*shared=*/false);
// The format doesn't matter, since we aren't binding.
scoped_refptr<GLImageDXGI> image_dxgi(
new GLImageDXGI(texture_size, nullptr));
image_dxgi->SetTexture(texture, /*level=*/0);
ui::DCRendererLayerParams params;
params.images[0] = image_dxgi;
params.content_rect = gfx::Rect(texture_size);
params.quad_rect = gfx::Rect(window_size);
EXPECT_TRUE(surface->ScheduleDCLayer(params));
}
EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing()));
const gfx::Size expected_size = for_video ? texture_size : window_size;
auto swap_chain = for_video ? surface->GetLayerSwapChainForTesting(0)
: surface->GetBackbufferSwapChainForTesting();
ASSERT_TRUE(swap_chain);
DXGI_SWAP_CHAIN_DESC1 desc;
EXPECT_TRUE(SUCCEEDED(swap_chain->GetDesc1(&desc)));
EXPECT_EQ(desc.Width, static_cast<UINT>(expected_size.width()));
EXPECT_EQ(desc.Height, static_cast<UINT>(expected_size.height()));
EXPECT_EQ(desc.BufferCount, buffer_count);
}
TEST_F(DirectCompositionSurfaceTest, RootSwapChainBufferCount) {
RunBufferCountTest(surface_, /*buffer_count=*/2u, /*for_video=*/false);
}
TEST_F(DirectCompositionSurfaceTest, VideoSwapChainBufferCount) {
RunBufferCountTest(surface_, /*buffer_count=*/2u, /*for_video=*/true);
}
class DirectCompositionTripleBufferingTest
: public DirectCompositionSurfaceTest {
public:
DirectCompositionTripleBufferingTest() = default;
~DirectCompositionTripleBufferingTest() override = default;
protected:
void SetUp() override {
feature_list_.InitWithFeatures({features::kDCompTripleBufferRootSwapChain,
features::kDCompTripleBufferVideoSwapChain},
{});
DirectCompositionSurfaceTest::SetUp();
}
private:
base::test::ScopedFeatureList feature_list_;
};
TEST_F(DirectCompositionTripleBufferingTest, MainSwapChainBufferCount) {
RunBufferCountTest(surface_, /*buffer_count=*/3u, /*for_video=*/false);
}
TEST_F(DirectCompositionTripleBufferingTest, VideoSwapChainBufferCount) {
RunBufferCountTest(surface_, /*buffer_count=*/3u, /*for_video=*/true);
}
} // namespace
} // namespace gl
......@@ -192,6 +192,14 @@ const int kGLSwitchesCopiedFromGpuProcessHostNumSwitches =
namespace features {
// Use BufferCount of 3 for the direct composition root swap chain.
const base::Feature kDCompTripleBufferRootSwapChain{
"DCompTripleBufferRootSwapChain", base::FEATURE_DISABLED_BY_DEFAULT};
// Use BufferCount of 3 for direct composition video swap chains.
const base::Feature kDCompTripleBufferVideoSwapChain{
"DCompTripleBufferVideoSwapChain", base::FEATURE_DISABLED_BY_DEFAULT};
// Forces Chrome's main backbuffer to full damage if the actual damage
// is large enough and allows DWM to consider the main backbuffer as an
// an overlay candidate.
......
......@@ -90,6 +90,8 @@ GL_EXPORT extern const int kGLSwitchesCopiedFromGpuProcessHostNumSwitches;
} // namespace switches
namespace features {
GL_EXPORT extern const base::Feature kDCompTripleBufferRootSwapChain;
GL_EXPORT extern const base::Feature kDCompTripleBufferVideoSwapChain;
GL_EXPORT extern const base::Feature kDirectCompositionForceFullDamage;
GL_EXPORT extern const base::Feature kDirectCompositionGpuVSync;
GL_EXPORT extern const base::Feature kDirectCompositionLowLatencyPresentation;
......
......@@ -124,6 +124,12 @@ UINT GetOverlaySupportFlags(DXGI_FORMAT format) {
return gl::DirectCompositionSurfaceWin::GetOverlaySupportFlags(format);
}
unsigned int DirectCompositionRootSurfaceBufferCount() {
return base::FeatureList::IsEnabled(features::kDCompTripleBufferRootSwapChain)
? 3u
: 2u;
}
bool ShouldForceDirectCompositionRootSurfaceFullDamage() {
static bool should_force = []() {
const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
......
......@@ -51,6 +51,9 @@ GL_EXPORT unsigned int FrameRateToPresentDuration(float frame_rate);
GL_EXPORT UINT GetOverlaySupportFlags(DXGI_FORMAT format);
// BufferCount for the root surface swap chain.
GL_EXPORT unsigned int DirectCompositionRootSurfaceBufferCount();
// Whether to use full damage when direct compostion root surface presents.
// This function is thread safe.
GL_EXPORT bool ShouldForceDirectCompositionRootSurfaceFullDamage();
......
......@@ -146,6 +146,13 @@ bool IsYUVSwapChainFormat(DXGI_FORMAT format) {
return true;
return false;
}
UINT BufferCount() {
return base::FeatureList::IsEnabled(
features::kDCompTripleBufferVideoSwapChain)
? 3u
: 2u;
}
} // namespace
SwapChainPresenter::PresentationHistory::PresentationHistory() = default;
......@@ -1155,7 +1162,7 @@ bool SwapChainPresenter::ReallocateSwapChain(
desc.Format = swap_chain_format;
desc.Stereo = FALSE;
desc.SampleDesc.Count = 1;
desc.BufferCount = 2;
desc.BufferCount = BufferCount();
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.Scaling = DXGI_SCALING_STRETCH;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
......
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