From 8602615cbbfe4d703e9e3a732b8c15f72b1ccd7e Mon Sep 17 00:00:00 2001 From: Sean Gilhuly Date: Wed, 6 Nov 2019 16:00:16 +0000 Subject: [PATCH] Add and plumb empty DawnContextProvider Prepare for Dawn as an option for compositing and raster by creating an empty implementation of the DawnContextProvider, which will use the Skia Dawn backend to create a GrContext. Compilation of DawnContextProvider and the Skia Dawn backend are enabled with the gn arg use_skia_dawn=true. The command line flag --gr-context-type=dawn will select SkiaRenderer Dawn at runtime. For now it doesn't connect with Dawn, and DawnContextProvider::Create() always returns nullptr. See crrev.com/c/1873874 for context. Bug: 1021566 Change-Id: Ifa8e17e5e8b8b3461f4177956a8e28f5bd8d27c0 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1896120 Commit-Queue: Sean Gilhuly Reviewed-by: Ken Buchanan Reviewed-by: Jonathan Backer Reviewed-by: Stephen White Cr-Commit-Position: refs/heads/master@{#713020} --- components/viz/common/BUILD.gn | 28 +++++++++++++++ .../viz/common/gpu/dawn_context_provider.cc | 22 ++++++++++++ .../viz/common/gpu/dawn_context_provider.h | 34 +++++++++++++++++++ .../common/viz_dawn_context_provider_export.h | 29 ++++++++++++++++ gpu/command_buffer/service/BUILD.gn | 6 ++++ gpu/command_buffer/service/DEPS | 2 ++ gpu/command_buffer/service/gpu_switches.cc | 1 + gpu/command_buffer/service/gpu_switches.h | 1 + gpu/command_buffer/service/service_utils.cc | 2 ++ .../service/shared_context_state.cc | 16 ++++++++- .../service/shared_context_state.h | 14 ++++++-- gpu/config/gpu_preferences.h | 3 +- gpu/ipc/common/gpu_preferences.mojom | 3 +- gpu/ipc/common/gpu_preferences_mojom_traits.h | 5 +++ gpu/ipc/service/gpu_channel_manager.cc | 10 +++--- gpu/ipc/service/gpu_channel_manager.h | 7 +++- skia/BUILD.gn | 9 ++++- skia/features.gni | 8 +++++ 18 files changed, 188 insertions(+), 12 deletions(-) create mode 100644 components/viz/common/gpu/dawn_context_provider.cc create mode 100644 components/viz/common/gpu/dawn_context_provider.h create mode 100644 components/viz/common/viz_dawn_context_provider_export.h create mode 100644 skia/features.gni diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index a3e12870079e9a..7c6a4256c1c851 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn @@ -4,6 +4,7 @@ import("//components/viz/viz.gni") import("//gpu/vulkan/features.gni") +import("//skia/features.gni") import("//testing/test.gni") source_set("resource_format") { @@ -40,6 +41,8 @@ viz_component("resource_format_utils") { ] } +# TODO(sgilhuly): To reduce link times, merge these context provider components +# into a single gr_context_provider component. if (is_mac) { viz_component("metal_context_provider") { output_name = "viz_metal_context_provider" @@ -107,6 +110,28 @@ if (enable_vulkan) { } } +if (skia_use_dawn) { + viz_component("dawn_context_provider") { + output_name = "viz_dawn_context_provider" + + defines = [ "VIZ_DAWN_CONTEXT_PROVIDER_IMPLEMENTATION" ] + + sources = [ + "gpu/dawn_context_provider.cc", + "gpu/dawn_context_provider.h", + "viz_dawn_context_provider_export.h", + ] + + public_deps = [ + "//skia", + ] + + deps = [ + "//base", + ] + } +} + viz_component("common") { output_name = "viz_common" @@ -302,6 +327,9 @@ viz_component("common") { if (is_mac) { public_deps += [ ":metal_context_provider" ] } + if (skia_use_dawn) { + public_deps += [ ":dawn_context_provider" ] + } } viz_source_set("unit_tests") { diff --git a/components/viz/common/gpu/dawn_context_provider.cc b/components/viz/common/gpu/dawn_context_provider.cc new file mode 100644 index 00000000000000..0321686f232f36 --- /dev/null +++ b/components/viz/common/gpu/dawn_context_provider.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/viz/common/gpu/dawn_context_provider.h" + +#include "base/memory/ptr_util.h" + +namespace viz { + +std::unique_ptr DawnContextProvider::Create() { + auto context_provider = base::WrapUnique(new DawnContextProvider()); + if (!context_provider->IsValid()) + return nullptr; + return context_provider; +} + +DawnContextProvider::DawnContextProvider() = default; + +DawnContextProvider::~DawnContextProvider() = default; + +} // namespace viz diff --git a/components/viz/common/gpu/dawn_context_provider.h b/components/viz/common/gpu/dawn_context_provider.h new file mode 100644 index 00000000000000..ef88a8aaaf6499 --- /dev/null +++ b/components/viz/common/gpu/dawn_context_provider.h @@ -0,0 +1,34 @@ +// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_VIZ_COMMON_GPU_DAWN_CONTEXT_PROVIDER_H_ +#define COMPONENTS_VIZ_COMMON_GPU_DAWN_CONTEXT_PROVIDER_H_ + +#include "base/macros.h" +#include "components/viz/common/viz_dawn_context_provider_export.h" +#include "third_party/skia/include/gpu/GrContext.h" + +class GrContext; + +namespace viz { + +class VIZ_DAWN_CONTEXT_PROVIDER_EXPORT DawnContextProvider { + public: + static std::unique_ptr Create(); + ~DawnContextProvider(); + + GrContext* GetGrContext() { return gr_context_.get(); } + bool IsValid() { return !!gr_context_; } + + private: + DawnContextProvider(); + + sk_sp gr_context_; + + DISALLOW_COPY_AND_ASSIGN(DawnContextProvider); +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_COMMON_GPU_DAWN_CONTEXT_PROVIDER_H_ diff --git a/components/viz/common/viz_dawn_context_provider_export.h b/components/viz/common/viz_dawn_context_provider_export.h new file mode 100644 index 00000000000000..d7725b9b9c20a1 --- /dev/null +++ b/components/viz/common/viz_dawn_context_provider_export.h @@ -0,0 +1,29 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_VIZ_COMMON_VIZ_DAWN_CONTEXT_PROVIDER_EXPORT_H_ +#define COMPONENTS_VIZ_COMMON_VIZ_DAWN_CONTEXT_PROVIDER_EXPORT_H_ + +#if defined(COMPONENT_BUILD) +#if defined(WIN32) + +#if defined(VIZ_DAWN_CONTEXT_PROVIDER_IMPLEMENTATION) +#define VIZ_DAWN_CONTEXT_PROVIDER_EXPORT __declspec(dllexport) +#else +#define VIZ_DAWN_CONTEXT_PROVIDER_EXPORT __declspec(dllimport) +#endif // defined(VIZ_DAWN_CONTEXT_PROVIDER_IMPLEMENTATION) + +#else // defined(WIN32) +#if defined(VIZ_DAWN_CONTEXT_PROVIDER_IMPLEMENTATION) +#define VIZ_DAWN_CONTEXT_PROVIDER_EXPORT __attribute__((visibility("default"))) +#else +#define VIZ_DAWN_CONTEXT_PROVIDER_EXPORT +#endif +#endif + +#else // defined(COMPONENT_BUILD) +#define VIZ_DAWN_CONTEXT_PROVIDER_EXPORT +#endif + +#endif // COMPONENTS_VIZ_COMMON_VIZ_DAWN_CONTEXT_PROVIDER_EXPORT_H_ diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index 77834c7fe6afbf..d919667667d84d 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn @@ -5,6 +5,7 @@ import("//build/config/jumbo.gni") import("//build/config/ui.gni") import("//gpu/vulkan/features.gni") +import("//skia/features.gni") import("//third_party/protobuf/proto_library.gni") import("//ui/gl/features.gni") @@ -309,6 +310,7 @@ target(link_target_type, "gles2_sources") { "//gpu/config", "//gpu/ipc/common", "//gpu/vulkan:buildflags", + "//skia:buildflags", "//third_party/angle:angle_image_util", "//third_party/angle:commit_id", "//third_party/angle:translator", @@ -371,6 +373,10 @@ target(link_target_type, "gles2_sources") { ] } + if (skia_use_dawn) { + deps += [ "//components/viz/common:dawn_context_provider" ] + } + if (is_android) { if (!is_debug) { # On Android optimize more since this component can be a bottleneck. diff --git a/gpu/command_buffer/service/DEPS b/gpu/command_buffer/service/DEPS index 1eed74db592d99..ee97fc38e531cd 100644 --- a/gpu/command_buffer/service/DEPS +++ b/gpu/command_buffer/service/DEPS @@ -1,7 +1,9 @@ include_rules = [ "+cc/paint", + "+skia", "+third_party/skia", "+components/crash/core/common/crash_key.h", + "+components/viz/common/gpu/dawn_context_provider.h", "+components/viz/common/gpu/metal_context_provider.h", "+components/viz/common/gpu/vulkan_context_provider.h", "+components/viz/common/resources/resource_format.h", diff --git a/gpu/command_buffer/service/gpu_switches.cc b/gpu/command_buffer/service/gpu_switches.cc index 35b0614c9869a4..f9aadc74c5753c 100644 --- a/gpu/command_buffer/service/gpu_switches.cc +++ b/gpu/command_buffer/service/gpu_switches.cc @@ -67,6 +67,7 @@ const char kGrContextType[] = "gr-context-type"; const char kGrContextTypeGL[] = "gl"; const char kGrContextTypeVulkan[] = "vulkan"; const char kGrContextTypeMetal[] = "metal"; +const char kGrContextTypeDawn[] = "dawn"; // Enable Vulkan support and select Vulkan implementation, must also have // ENABLE_VULKAN defined. const char kUseVulkan[] = "use-vulkan"; diff --git a/gpu/command_buffer/service/gpu_switches.h b/gpu/command_buffer/service/gpu_switches.h index 3aa3fccdc067cc..ee702988014aeb 100644 --- a/gpu/command_buffer/service/gpu_switches.h +++ b/gpu/command_buffer/service/gpu_switches.h @@ -32,6 +32,7 @@ GPU_EXPORT extern const char kGrContextType[]; GPU_EXPORT extern const char kGrContextTypeGL[]; GPU_EXPORT extern const char kGrContextTypeVulkan[]; GPU_EXPORT extern const char kGrContextTypeMetal[]; +GPU_EXPORT extern const char kGrContextTypeDawn[]; GPU_EXPORT extern const char kVulkanImplementationNameNative[]; GPU_EXPORT extern const char kUseVulkan[]; GPU_EXPORT extern const char kVulkanImplementationNameNative[]; diff --git a/gpu/command_buffer/service/service_utils.cc b/gpu/command_buffer/service/service_utils.cc index d144c0743c7005..7f62b05c0349c5 100644 --- a/gpu/command_buffer/service/service_utils.cc +++ b/gpu/command_buffer/service/service_utils.cc @@ -179,6 +179,8 @@ GpuPreferences ParseGpuPreferences(const base::CommandLine* command_line) { << "GrContextType is Metal, but Metal is not enabled."; gpu_preferences.gr_context_type = GrContextType::kMetal; #endif + } else if (value == switches::kGrContextTypeDawn) { + gpu_preferences.gr_context_type = GrContextType::kDawn; } else { NOTREACHED() << "Invalid GrContextType."; gpu_preferences.gr_context_type = GrContextType::kGL; diff --git a/gpu/command_buffer/service/shared_context_state.cc b/gpu/command_buffer/service/shared_context_state.cc index b1127ff09bcccc..84fb4cf309c9b5 100644 --- a/gpu/command_buffer/service/shared_context_state.cc +++ b/gpu/command_buffer/service/shared_context_state.cc @@ -13,6 +13,7 @@ #include "gpu/command_buffer/service/service_utils.h" #include "gpu/config/gpu_driver_bug_workarounds.h" #include "gpu/vulkan/buildflags.h" +#include "skia/buildflags.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_share_group.h" @@ -28,6 +29,10 @@ #include "components/viz/common/gpu/metal_context_provider.h" #endif +#if BUILDFLAG(SKIA_USE_DAWN) +#include "components/viz/common/gpu/dawn_context_provider.h" +#endif + namespace { static constexpr size_t kInitialScratchDeserializationBufferSize = 1024; } @@ -51,12 +56,14 @@ SharedContextState::SharedContextState( base::OnceClosure context_lost_callback, GrContextType gr_context_type, viz::VulkanContextProvider* vulkan_context_provider, - viz::MetalContextProvider* metal_context_provider) + viz::MetalContextProvider* metal_context_provider, + viz::DawnContextProvider* dawn_context_provider) : use_virtualized_gl_contexts_(use_virtualized_gl_contexts), context_lost_callback_(std::move(context_lost_callback)), gr_context_type_(gr_context_type), vk_context_provider_(vulkan_context_provider), metal_context_provider_(metal_context_provider), + dawn_context_provider_(dawn_context_provider), share_group_(std::move(share_group)), context_(context), real_context_(std::move(context)), @@ -77,6 +84,13 @@ SharedContextState::SharedContextState( use_virtualized_gl_contexts_ = false; DCHECK(gr_context_); } + if (GrContextIsDawn()) { +#if BUILDFLAG(SKIA_USE_DAWN) + gr_context_ = dawn_context_provider_->GetGrContext(); +#endif + use_virtualized_gl_contexts_ = false; + DCHECK(gr_context_); + } if (base::ThreadTaskRunnerHandle::IsSet()) { base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( diff --git a/gpu/command_buffer/service/shared_context_state.h b/gpu/command_buffer/service/shared_context_state.h index 6ceaa8c6e17755..1d9713b81dac2c 100644 --- a/gpu/command_buffer/service/shared_context_state.h +++ b/gpu/command_buffer/service/shared_context_state.h @@ -28,6 +28,7 @@ class GLSurface; } // namespace gl namespace viz { +class DawnContextProvider; class MetalContextProvider; class VulkanContextProvider; } // namespace viz @@ -58,7 +59,8 @@ class GPU_GLES2_EXPORT SharedContextState base::OnceClosure context_lost_callback, GrContextType gr_context_type = GrContextType::kGL, viz::VulkanContextProvider* vulkan_context_provider = nullptr, - viz::MetalContextProvider* metal_context_provider = nullptr); + viz::MetalContextProvider* metal_context_provider = nullptr, + viz::DawnContextProvider* dawn_context_provider = nullptr); void InitializeGrContext(const GpuDriverBugWorkarounds& workarounds, GrContextOptions::PersistentCache* cache, @@ -71,8 +73,10 @@ class GPU_GLES2_EXPORT SharedContextState return vk_context_provider_ && gr_context_type_ == GrContextType::kVulkan; } bool GrContextIsMetal() const { - return metal_context_provider_ && - gr_context_type_ == GrContextType::kMetal; + return metal_context_provider_ && gr_context_type_ == GrContextType::kMetal; + } + bool GrContextIsDawn() const { + return dawn_context_provider_ && gr_context_type_ == GrContextType::kDawn; } bool InitializeGL(const GpuPreferences& gpu_preferences, @@ -98,6 +102,9 @@ class GPU_GLES2_EXPORT SharedContextState viz::MetalContextProvider* metal_context_provider() { return metal_context_provider_; } + viz::DawnContextProvider* dawn_context_provider() { + return dawn_context_provider_; + } gl::ProgressReporter* progress_reporter() const { return progress_reporter_; } GrContext* gr_context() { return gr_context_; } // Handles Skia-reported shader compilation errors. @@ -170,6 +177,7 @@ class GPU_GLES2_EXPORT SharedContextState GrContextType gr_context_type_ = GrContextType::kGL; viz::VulkanContextProvider* const vk_context_provider_; viz::MetalContextProvider* const metal_context_provider_; + viz::DawnContextProvider* const dawn_context_provider_; GrContext* gr_context_ = nullptr; scoped_refptr share_group_; diff --git a/gpu/config/gpu_preferences.h b/gpu/config/gpu_preferences.h index 4a0b40522384bf..3752b5cb693251 100644 --- a/gpu/config/gpu_preferences.h +++ b/gpu/config/gpu_preferences.h @@ -41,7 +41,8 @@ enum class GrContextType : uint32_t { kGL = 0, kVulkan = 1, kMetal = 2, - kLast = kMetal, + kDawn = 3, + kLast = kDawn, }; // NOTE: if you modify this structure then you must also modify the diff --git a/gpu/ipc/common/gpu_preferences.mojom b/gpu/ipc/common/gpu_preferences.mojom index 3e70fa78b303d3..9a629106bac15b 100644 --- a/gpu/ipc/common/gpu_preferences.mojom +++ b/gpu/ipc/common/gpu_preferences.mojom @@ -24,7 +24,8 @@ enum GrContextType { kGL = 0, kVulkan = 1, kMetal = 2, - kLast = kMetal, + kDawn = 3, + kLast = kDawn, }; // gpu::GpuPreferences diff --git a/gpu/ipc/common/gpu_preferences_mojom_traits.h b/gpu/ipc/common/gpu_preferences_mojom_traits.h index 26ce3108d56dae..e776ef7f2760fc 100644 --- a/gpu/ipc/common/gpu_preferences_mojom_traits.h +++ b/gpu/ipc/common/gpu_preferences_mojom_traits.h @@ -28,6 +28,8 @@ struct EnumTraits { return gpu::mojom::GrContextType::kVulkan; case gpu::GrContextType::kMetal: return gpu::mojom::GrContextType::kMetal; + case gpu::GrContextType::kDawn: + return gpu::mojom::GrContextType::kDawn; } NOTREACHED(); return gpu::mojom::GrContextType::kGL; @@ -44,6 +46,9 @@ struct EnumTraits { case gpu::mojom::GrContextType::kMetal: *out = gpu::GrContextType::kMetal; return true; + case gpu::mojom::GrContextType::kDawn: + *out = gpu::GrContextType::kDawn; + return true; } return false; } diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc index 155e6d8c4d37f8..965a05b5a07617 100644 --- a/gpu/ipc/service/gpu_channel_manager.cc +++ b/gpu/ipc/service/gpu_channel_manager.cc @@ -110,7 +110,8 @@ GpuChannelManager::GpuChannelManager( scoped_refptr default_offscreen_surface, ImageDecodeAcceleratorWorker* image_decode_accelerator_worker, viz::VulkanContextProvider* vulkan_context_provider, - viz::MetalContextProvider* metal_context_provider) + viz::MetalContextProvider* metal_context_provider, + viz::DawnContextProvider* dawn_context_provider) : task_runner_(task_runner), io_task_runner_(io_task_runner), gpu_preferences_(gpu_preferences), @@ -133,7 +134,8 @@ GpuChannelManager::GpuChannelManager( base::BindRepeating(&GpuChannelManager::HandleMemoryPressure, base::Unretained(this))), vulkan_context_provider_(vulkan_context_provider), - metal_context_provider_(metal_context_provider) { + metal_context_provider_(metal_context_provider), + dawn_context_provider_(dawn_context_provider) { DCHECK(task_runner->BelongsToCurrentThread()); DCHECK(io_task_runner); DCHECK(scheduler); @@ -481,8 +483,8 @@ scoped_refptr GpuChannelManager::GetSharedContextState( use_virtualized_gl_contexts, base::BindOnce(&GpuChannelManager::OnContextLost, base::Unretained(this), /*synthetic_loss=*/false), - gpu_preferences_.gr_context_type, - vulkan_context_provider_, metal_context_provider_); + gpu_preferences_.gr_context_type, vulkan_context_provider_, + metal_context_provider_, dawn_context_provider_); // OOP-R needs GrContext for raster tiles. bool need_gr_context = diff --git a/gpu/ipc/service/gpu_channel_manager.h b/gpu/ipc/service/gpu_channel_manager.h index 6ef78efe555948..217adb652cb1e1 100644 --- a/gpu/ipc/service/gpu_channel_manager.h +++ b/gpu/ipc/service/gpu_channel_manager.h @@ -83,7 +83,8 @@ class GPU_IPC_SERVICE_EXPORT GpuChannelManager scoped_refptr default_offscreen_surface, ImageDecodeAcceleratorWorker* image_decode_accelerator_worker, viz::VulkanContextProvider* vulkan_context_provider = nullptr, - viz::MetalContextProvider* metal_context_provider = nullptr); + viz::MetalContextProvider* metal_context_provider = nullptr, + viz::DawnContextProvider* dawn_context_provider = nullptr); ~GpuChannelManager() override; GpuChannelManagerDelegate* delegate() const { return delegate_; } @@ -296,6 +297,10 @@ class GPU_IPC_SERVICE_EXPORT GpuChannelManager // viz::GpuServiceImpl. The raster decoders will use it for rasterization. viz::MetalContextProvider* metal_context_provider_ = nullptr; + // With --gr-context-type=dawn, |dawn_context_provider_| will be set from + // viz::GpuServiceImpl. The raster decoders will use it for rasterization. + viz::DawnContextProvider* dawn_context_provider_ = nullptr; + GpuPeakMemoryMonitor peak_memory_monitor_; // Member variables should appear before the WeakPtrFactory, to ensure diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 1d2253b3a2651e..87ee29d059c364 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn @@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/buildflag_header.gni") import("//build/config/compiler/compiler.gni") import("//build/config/features.gni") import("//build/config/freetype/freetype.gni") @@ -11,6 +12,7 @@ import("//printing/buildflags/buildflags.gni") import("//testing/test.gni") import("//third_party/skia/gn/shared_sources.gni") import("//third_party/skia/third_party/skcms/skcms.gni") +import("features.gni") if (current_cpu == "arm") { import("//build/config/arm.gni") @@ -26,7 +28,12 @@ skia_support_skottie = true declare_args() { enable_skia_wuffs_gif = false skia_whitelist_serialized_typefaces = false - skia_use_dawn = false +} + +# Generate a buildflag header for compile-time checking of Dawn support. +buildflag_header("buildflags") { + header = "buildflags.h" + flags = [ "SKIA_USE_DAWN=$skia_use_dawn" ] } # External-facing config for dependent code. diff --git a/skia/features.gni b/skia/features.gni new file mode 100644 index 00000000000000..f8ee32ea49527d --- /dev/null +++ b/skia/features.gni @@ -0,0 +1,8 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +declare_args() { + # Enable experimental SkiaRenderer Dawn backend. + skia_use_dawn = false +}