From 312bfb7b121794deee080a52a7b970fa1603a387 Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Mon, 28 Jun 2021 13:30:34 -0700 Subject: [PATCH 1/2] Configure contexts to reduce shader variations. Context creation options for each backend were spread across multiple translation units. This makes setting options common across all backends hard to configure. I have moved the creation of such common options into a separate translation unit. Fixes https://github.com/flutter/flutter/issues/84213 --- ci/licenses_golden/licenses_flutter | 2 + shell/common/BUILD.gn | 2 + shell/common/context_options.cc | 39 +++++++++++++++++ shell/common/context_options.h | 43 +++++++++++++++++++ shell/common/platform_view.cc | 1 - shell/common/shell_io_manager.cc | 26 +---------- .../common/shell_test_platform_view_vulkan.cc | 10 ++--- shell/gpu/gpu_surface_gl.cc | 23 ++-------- shell/platform/darwin/graphics/BUILD.gn | 1 + .../graphics/FlutterDarwinContextMetal.mm | 19 +++----- .../fuchsia/flutter/platform_view_unittest.cc | 6 ++- .../flutter/vulkan_surface_producer.cc | 6 +-- 12 files changed, 107 insertions(+), 71 deletions(-) create mode 100644 shell/common/context_options.cc create mode 100644 shell/common/context_options.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index b6d5dbce78b8c..b6275cbb34843 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -671,6 +671,8 @@ FILE: ../../../flutter/shell/common/animator_unittests.cc FILE: ../../../flutter/shell/common/canvas_spy.cc FILE: ../../../flutter/shell/common/canvas_spy.h FILE: ../../../flutter/shell/common/canvas_spy_unittests.cc +FILE: ../../../flutter/shell/common/context_options.cc +FILE: ../../../flutter/shell/common/context_options.h FILE: ../../../flutter/shell/common/display.h FILE: ../../../flutter/shell/common/display_manager.cc FILE: ../../../flutter/shell/common/display_manager.h diff --git a/shell/common/BUILD.gn b/shell/common/BUILD.gn index 0e24c721d7019..d7c4f09eabf49 100644 --- a/shell/common/BUILD.gn +++ b/shell/common/BUILD.gn @@ -64,6 +64,8 @@ source_set("common") { "animator.h", "canvas_spy.cc", "canvas_spy.h", + "context_options.cc", + "context_options.h", "display.h", "display_manager.cc", "display_manager.h", diff --git a/shell/common/context_options.cc b/shell/common/context_options.cc new file mode 100644 index 0000000000000..4fea8fe7d4834 --- /dev/null +++ b/shell/common/context_options.cc @@ -0,0 +1,39 @@ +// Copyright 2013 The Flutter 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 "flutter/shell/common/context_options.h" + +#include "flutter/common/graphics/persistent_cache.h" + +namespace flutter { + +GrContextOptions MakeDefaultContextOptions(ContextType type, + std::optional api) { + GrContextOptions options; + + if (PersistentCache::cache_sksl()) { + options.fShaderCacheStrategy = GrContextOptions::ShaderCacheStrategy::kSkSL; + } + PersistentCache::MarkStrategySet(); + options.fPersistentCache = PersistentCache::GetCacheForProcess(); + + if (api.has_value() && api.value() == GrBackendApi::kOpenGL) { + options.fAvoidStencilBuffers = true; + + // To get video playback on the widest range of devices, we limit Skia to + // ES2 shading language when the ES3 external image extension is missing. + options.fPreferExternalImagesOverES3 = true; + } + + // TODO(goderbauer): remove option when skbug.com/7523 is fixed. + options.fDisableGpuYUVConversion = true; + + options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; + + options.fReducedShaderVariations = true; + + return options; +}; + +} // namespace flutter diff --git a/shell/common/context_options.h b/shell/common/context_options.h new file mode 100644 index 0000000000000..bae0b2fb8e4e4 --- /dev/null +++ b/shell/common/context_options.h @@ -0,0 +1,43 @@ +// Copyright 2013 The Flutter 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 FLUTTER_SHELL_COMMON_CONTEXT_OPTIONS_H_ +#define FLUTTER_SHELL_COMMON_CONTEXT_OPTIONS_H_ + +#include + +#include "flutter/fml/macros.h" +#include "third_party/skia/include/gpu/GrContextOptions.h" + +namespace flutter { + +enum class ContextType { + /// The context is used to render to a texture or renderbuffer. + kRender, + /// The context will only be used to transfer resources to and from device + /// memory. No rendering will be performed using this context. + kResource, +}; + +//------------------------------------------------------------------------------ +/// @brief Initializes GrContextOptions with values suitable for Flutter. +/// The options can be further tweaked before a GrContext is created +/// from these options. +/// +/// @param[in] type The type of context that will be created using these +/// options. +/// @param[in] type The client rendering API that will be wrapped using a +/// context with these options. This argument is only required +/// if the context is going to be used with a particular +/// client rendering API. +/// +/// @return The default graphics context options. +/// +GrContextOptions MakeDefaultContextOptions( + ContextType type, + std::optional api = std::nullopt); + +} // namespace flutter + +#endif // FLUTTER_SHELL_COMMON_CONTEXT_OPTIONS_H_ diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 7c7b4dd1d421e..b2c552599e547 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -11,7 +11,6 @@ #include "flutter/shell/common/rasterizer.h" #include "flutter/shell/common/shell.h" #include "flutter/shell/common/vsync_waiter_fallback.h" -#include "third_party/skia/include/gpu/GrContextOptions.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" namespace flutter { diff --git a/shell/common/shell_io_manager.cc b/shell/common/shell_io_manager.cc index cf90a73bfe1a5..264ea5a32d8ce 100644 --- a/shell/common/shell_io_manager.cc +++ b/shell/common/shell_io_manager.cc @@ -7,6 +7,7 @@ #include "flutter/common/graphics/persistent_cache.h" #include "flutter/fml/build_config.h" #include "flutter/fml/message_loop.h" +#include "flutter/shell/common/context_options.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" namespace flutter { @@ -18,30 +19,7 @@ sk_sp ShellIOManager::CreateCompatibleResourceLoadingContext( return nullptr; } - GrContextOptions options = {}; - - if (PersistentCache::cache_sksl()) { - FML_LOG(INFO) << "Cache SkSL"; - options.fShaderCacheStrategy = GrContextOptions::ShaderCacheStrategy::kSkSL; - } - PersistentCache::MarkStrategySet(); - - options.fPersistentCache = PersistentCache::GetCacheForProcess(); - - // There is currently a bug with doing GPU YUV to RGB conversions on the IO - // thread. The necessary work isn't being flushed or synchronized with the - // other threads correctly, so the textures end up blank. For now, suppress - // that feature, which will cause texture uploads to do CPU YUV conversion. - // A similar work-around is also used in shell/gpu/gpu_surface_gl.cc. - options.fDisableGpuYUVConversion = true; - - // To get video playback on the widest range of devices, we limit Skia to - // ES2 shading language when the ES3 external image extension is missing. - options.fPreferExternalImagesOverES3 = true; - - // Enabling this flag can increase VRAM consumption. Turn it off until - // further notice. - options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; + const auto options = MakeDefaultContextOptions(ContextType::kResource); #if !OS_FUCHSIA if (auto context = GrDirectContext::MakeGL(gl_interface, options)) { diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 29f6aba2becc1..754133c514f0e 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -5,6 +5,7 @@ #include "flutter/shell/common/shell_test_platform_view_vulkan.h" #include "flutter/common/graphics/persistent_cache.h" +#include "flutter/shell/common/context_options.h" #include "flutter/vulkan/vulkan_utilities.h" namespace flutter { @@ -113,13 +114,8 @@ bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaGrContext() { return false; } - GrContextOptions options; - if (PersistentCache::cache_sksl()) { - options.fShaderCacheStrategy = GrContextOptions::ShaderCacheStrategy::kSkSL; - } - PersistentCache::MarkStrategySet(); - options.fPersistentCache = PersistentCache::GetCacheForProcess(); - options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; + const auto options = + MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kVulkan); sk_sp context = GrDirectContext::MakeVulkan(backend_context, options); diff --git a/shell/gpu/gpu_surface_gl.cc b/shell/gpu/gpu_surface_gl.cc index e04a9a2556189..e78135663764b 100644 --- a/shell/gpu/gpu_surface_gl.cc +++ b/shell/gpu/gpu_surface_gl.cc @@ -9,6 +9,7 @@ #include "flutter/fml/logging.h" #include "flutter/fml/size.h" #include "flutter/fml/trace_event.h" +#include "flutter/shell/common/context_options.h" #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" @@ -43,26 +44,8 @@ sk_sp GPUSurfaceGL::MakeGLContext( return nullptr; } - GrContextOptions options; - - if (PersistentCache::cache_sksl()) { - FML_LOG(INFO) << "Cache SkSL"; - options.fShaderCacheStrategy = GrContextOptions::ShaderCacheStrategy::kSkSL; - } - PersistentCache::MarkStrategySet(); - options.fPersistentCache = PersistentCache::GetCacheForProcess(); - - options.fAvoidStencilBuffers = true; - - // To get video playback on the widest range of devices, we limit Skia to - // ES2 shading language when the ES3 external image extension is missing. - options.fPreferExternalImagesOverES3 = true; - - // TODO(goderbauer): remove option when skbug.com/7523 is fixed. - // A similar work-around is also used in shell/common/io_manager.cc. - options.fDisableGpuYUVConversion = true; - - options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; + const auto options = + MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kOpenGL); auto context = GrDirectContext::MakeGL(delegate->GetGLInterface(), options); diff --git a/shell/platform/darwin/graphics/BUILD.gn b/shell/platform/darwin/graphics/BUILD.gn index 7dd998a48f6a9..bf49f796af3b8 100644 --- a/shell/platform/darwin/graphics/BUILD.gn +++ b/shell/platform/darwin/graphics/BUILD.gn @@ -20,6 +20,7 @@ source_set("graphics") { deps = [ "//flutter/common/graphics", "//flutter/fml", + "//flutter/shell/common", "//flutter/shell/platform/darwin/common:framework_shared", ] diff --git a/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm b/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm index 6beab111e2ed8..8c90d4bacf15f 100644 --- a/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm +++ b/shell/platform/darwin/graphics/FlutterDarwinContextMetal.mm @@ -7,21 +7,10 @@ #include "flutter/common/graphics/persistent_cache.h" #include "flutter/fml/logging.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" -#include "third_party/skia/include/gpu/GrContextOptions.h" +#include "shell/common/context_options.h" FLUTTER_ASSERT_ARC -static GrContextOptions CreateMetalGrContextOptions() { - GrContextOptions options = {}; - if (flutter::PersistentCache::cache_sksl()) { - options.fShaderCacheStrategy = GrContextOptions::ShaderCacheStrategy::kSkSL; - } - flutter::PersistentCache::MarkStrategySet(); - options.fPersistentCache = flutter::PersistentCache::GetCacheForProcess(); - options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; - return options; -} - @implementation FlutterDarwinContextMetal - (instancetype)initWithDefaultMTLDevice { @@ -77,7 +66,8 @@ - (instancetype)initWithMTLDevice:(id)device } - (sk_sp)createGrContext { - auto contextOptions = CreateMetalGrContextOptions(); + const auto contextOptions = + flutter::MakeDefaultContextOptions(flutter::ContextType::kRender, GrBackendApi::kMetal); id device = _device; id commandQueue = _commandQueue; return [FlutterDarwinContextMetal createGrContext:device commandQueue:commandQueue]; @@ -85,7 +75,8 @@ - (instancetype)initWithMTLDevice:(id)device + (sk_sp)createGrContext:(id)device commandQueue:(id)commandQueue { - auto contextOptions = CreateMetalGrContextOptions(); + const auto contextOptions = + flutter::MakeDefaultContextOptions(flutter::ContextType::kRender, GrBackendApi::kMetal); // Skia expect arguments to `MakeMetal` transfer ownership of the reference in for release later // when the GrDirectContext is collected. return GrDirectContext::MakeMetal((__bridge_retained void*)device, diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index e0e8c37ebd271..f26e29226e5fd 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -20,6 +20,7 @@ #include "flutter/flow/embedded_views.h" #include "flutter/lib/ui/window/platform_message.h" #include "flutter/lib/ui/window/viewport_metrics.h" +#include "flutter/shell/common/context_options.h" #include "flutter/shell/platform/fuchsia/flutter/platform_view.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -347,8 +348,9 @@ TEST_F(PlatformViewTests, CreateSurfaceTest) { ); // Test create surface callback function. - sk_sp gr_context = - GrDirectContext::MakeMock(nullptr, GrContextOptions()); + sk_sp gr_context = GrDirectContext::MakeMock( + nullptr, + flutter::MakeDefaultContextOptions(flutter::ContextType::kRender)); std::shared_ptr view_embedder = std::make_shared(); auto CreateSurfaceCallback = [&view_embedder, gr_context]() { diff --git a/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc b/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc index 53bf3b3eae6cf..7cd757e5cc737 100644 --- a/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc +++ b/shell/platform/fuchsia/flutter/vulkan_surface_producer.cc @@ -12,6 +12,7 @@ #include #include "flutter/fml/trace_event.h" +#include "flutter/shell/common/context_options.h" #include "third_party/skia/include/gpu/GrBackendSemaphore.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" @@ -137,9 +138,8 @@ bool VulkanSurfaceProducer::Initialize(scenic::Session* scenic_session) { backend_context.fPhysicalDevice, 0, nullptr, countof(device_extensions), device_extensions); backend_context.fVkExtensions = &vk_extensions; - GrContextOptions options; - options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; - + const auto options = flutter::MakeDefaultContextOptions( + flutter::ContextType::kRender, GrBackendApi::kVulkan); context_ = GrDirectContext::MakeVulkan(backend_context, options); if (context_ == nullptr) { From a6947da2ea9cda57c5386c90edb56f01ac6d35b6 Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Mon, 28 Jun 2021 14:38:08 -0700 Subject: [PATCH 2/2] Update embedder_unittest fixtures. --- shell/platform/embedder/fixtures/gradient.png | Bin 33551 -> 33533 bytes .../embedder/fixtures/gradient_xform.png | Bin 34241 -> 34230 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/shell/platform/embedder/fixtures/gradient.png b/shell/platform/embedder/fixtures/gradient.png index 27b69ecbb85c3378360309a32dc3bcc3bf7aa76f..bf9647518e08bcf6ca38faf4eba7602368808472 100644 GIT binary patch delta 10641 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 O;cZ)NH)n71I`co4R*r)J delta 10795 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 AdjJ3c diff --git a/shell/platform/embedder/fixtures/gradient_xform.png b/shell/platform/embedder/fixtures/gradient_xform.png index 186b98e87e69ab88bec5d52ac6d8a04aa967771c..b51524e6b203dccb95b2914b0ec9e7db02d7f17d 100644 GIT binary patch delta 4770 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 Wk7p0h4_ASIU##?7aqe^Kp8o@PIL=uB delta 4857 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