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 +}