From ddece8ea29d5bb3a0f8cd83a17e54d35a9a0ed13 Mon Sep 17 00:00:00 2001 From: Forrest Reiling Date: Fri, 14 Feb 2020 11:29:59 -0800 Subject: [PATCH 1/3] [shell tests] Integrate Vulkan with Shell Tests This change creates a test only implementation of flutter::Surface backed by an offscreen Vulkan GrContext. Much of the code in this test Surface was lifted from flutter::VulkanWindow which I was unable to use without extricating it from the VkSurface/VkSwapchain code which we do not want to use in offscreen tests. I would recommend refactoring VulkanWindow to separate GrContext creation and VkSwapchain creation in order to promote greater code reuse between onscreen and offscreen vulkan paths. This change is excersised thoroughly by the shell tests and was manually tested against these tests on Fuchsia on Intel. --- .../common/shell_test_platform_view_vulkan.cc | 128 +++++++++++++++++- .../common/shell_test_platform_view_vulkan.h | 38 +++++- testing/fuchsia/meta/fuchsia_test.cmx | 7 +- 3 files changed, 162 insertions(+), 11 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index b582931748839..95c987d38da6e 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "flutter/shell/common/shell_test_platform_view_vulkan.h" -#include "flutter/shell/gpu/gpu_surface_vulkan.h" namespace flutter { namespace testing { @@ -30,7 +29,7 @@ void ShellTestPlatformViewVulkan::SimulateVSync() { // |PlatformView| std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface() { - return std::make_unique(this, nullptr, true); + return std::make_unique(proc_table_); } // |PlatformView| @@ -40,9 +39,128 @@ PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() { }; } -// |GPUSurfaceVulkanDelegate| -fml::RefPtr ShellTestPlatformViewVulkan::vk() { - return proc_table_; +ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( + fml::RefPtr vk) + : valid_(false), vk_(std::move(vk)) { + if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { + FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; + return; + } + + // Create the application instance. + std::vector extensions = {}; + + application_ = std::make_unique( + *vk_, "FlutterTest", std::move(extensions)); + + if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) { + // Make certain the application instance was created and it setup the + // instance proc table entries. + FML_DLOG(ERROR) << "Instance proc addresses have not been setup."; + return; + } + + // Create the device. + + logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); + + if (logical_device_ == nullptr || !logical_device_->IsValid() || + !vk_->AreDeviceProcsSetup()) { + // Make certain the device was created and it setup the device proc table + // entries. + FML_DLOG(ERROR) << "Device proc addresses have not been setup."; + return; + } + + // Create the Skia GrContext. + if (!CreateSkiaGrContext()) { + FML_DLOG(ERROR) << "Could not create Skia context."; + return; + } + + valid_ = true; +} + +bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaGrContext() { + GrVkBackendContext backend_context; + + if (!CreateSkiaBackendContext(&backend_context)) { + FML_DLOG(ERROR) << "Could not create Skia backend context."; + return false; + } + + sk_sp context = GrContext::MakeVulkan(backend_context); + + if (context == nullptr) { + FML_DLOG(ERROR) << "Failed to create GrContext"; + return false; + } + + context->setResourceCacheLimits(vulkan::kGrCacheMaxCount, + vulkan::kGrCacheMaxByteSize); + + context_ = context; + + return true; +} + +bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaBackendContext( + GrVkBackendContext* context) { + auto getProc = vk_->CreateSkiaGetProc(); + + if (getProc == nullptr) { + FML_DLOG(ERROR) << "GetProcAddress is null"; + return false; + } + + uint32_t skia_features = 0; + if (!logical_device_->GetPhysicalDeviceFeaturesSkia(&skia_features)) { + FML_DLOG(ERROR) << "Failed to get Physical Device features"; + return false; + } + + context->fInstance = application_->GetInstance(); + context->fPhysicalDevice = logical_device_->GetPhysicalDeviceHandle(); + context->fDevice = logical_device_->GetHandle(); + context->fQueue = logical_device_->GetQueueHandle(); + context->fGraphicsQueueIndex = logical_device_->GetGraphicsQueueIndex(); + context->fMinAPIVersion = application_->GetAPIVersion(); + context->fMaxAPIVersion = application_->GetAPIVersion(); + context->fFeatures = skia_features; + context->fGetProc = std::move(getProc); + context->fOwnsInstanceAndDevice = false; + return true; +} + +ShellTestPlatformViewVulkan::OffScreenSurface::~OffScreenSurface() {} + +bool ShellTestPlatformViewVulkan::OffScreenSurface::IsValid() { + return valid_; +} + +std::unique_ptr +ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame( + const SkISize& size) { + auto image_info = SkImageInfo::Make(size, SkColorType::kRGBA_8888_SkColorType, + SkAlphaType::kOpaque_SkAlphaType); + auto surface = SkSurface::MakeRenderTarget(context_.get(), SkBudgeted::kNo, + image_info, 0, nullptr); + SurfaceFrame::SubmitCallback callback = + [](const SurfaceFrame&, SkCanvas* canvas) -> bool { return true; }; + + return std::make_unique(std::move(surface), true, + std::move(callback)); +} + +GrContext* ShellTestPlatformViewVulkan::OffScreenSurface::GetContext() { + return context_.get(); +} + +SkMatrix ShellTestPlatformViewVulkan::OffScreenSurface::GetRootTransformation() + const { + SkMatrix matrix; + matrix.reset(); + return matrix; } } // namespace testing diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index c201ff1a9f27f..38bce87fa5414 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -7,12 +7,13 @@ #include "flutter/shell/common/shell_test_platform_view.h" #include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" +#include "flutter/vulkan/vulkan_application.h" +#include "flutter/vulkan/vulkan_device.h" namespace flutter { namespace testing { -class ShellTestPlatformViewVulkan : public ShellTestPlatformView, - public GPUSurfaceVulkanDelegate { +class ShellTestPlatformViewVulkan : public ShellTestPlatformView { public: ShellTestPlatformViewVulkan(PlatformView::Delegate& delegate, TaskRunners task_runners, @@ -24,6 +25,36 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView, void SimulateVSync() override; private: + class OffScreenSurface : public flutter::Surface { + public: + OffScreenSurface(fml::RefPtr vk); + + ~OffScreenSurface() override; + + // |Surface| + bool IsValid() override; + + // |Surface| + std::unique_ptr AcquireFrame(const SkISize& size) override; + + SkMatrix GetRootTransformation() const override; + + // |Surface| + GrContext* GetContext() override; + + private: + bool valid_; + fml::RefPtr vk_; + std::unique_ptr application_; + std::unique_ptr logical_device_; + sk_sp context_; + + bool CreateSkiaGrContext(); + bool CreateSkiaBackendContext(GrVkBackendContext* context); + + FML_DISALLOW_COPY_AND_ASSIGN(OffScreenSurface); + }; + CreateVsyncWaiter create_vsync_waiter_; std::shared_ptr vsync_clock_; @@ -39,9 +70,6 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView, // |PlatformView| PointerDataDispatcherMaker GetDispatcherMaker() override; - // |GPUSurfaceVulkanDelegate| - fml::RefPtr vk() override; - FML_DISALLOW_COPY_AND_ASSIGN(ShellTestPlatformViewVulkan); }; diff --git a/testing/fuchsia/meta/fuchsia_test.cmx b/testing/fuchsia/meta/fuchsia_test.cmx index 1eb7a22e5ef28..7239603b3f1ff 100644 --- a/testing/fuchsia/meta/fuchsia_test.cmx +++ b/testing/fuchsia/meta/fuchsia_test.cmx @@ -9,7 +9,12 @@ ], "services": [ "fuchsia.accessibility.semantics.SemanticsManager", - "fuchsia.process.Launcher" + "fuchsia.process.Launcher", + "fuchsia.deprecatedtimezone.Timezone", + "fuchsia.netstack.Netstack", + "fuchsia.vulkan.loader.Loader", + "fuchsia.logger.LogSink", + "fuchsia.tracing.provider.Registry" ] } } From 71bd7c1d89eda279c8f9e29fd34356536560a387 Mon Sep 17 00:00:00 2001 From: George Wright Date: Thu, 20 Feb 2020 10:41:23 -0800 Subject: [PATCH 2/3] Add a todo --- shell/common/shell_test_platform_view_vulkan.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 95c987d38da6e..f8e1000c697bd 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -39,6 +39,9 @@ PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() { }; } +// TODO(gw280): This code was forked from vulkan_window.cc specifically for shell_test. +// We need to merge this functionality back into //vulkan. +// https://github.com/flutter/flutter/issues/51132 ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( fml::RefPtr vk) : valid_(false), vk_(std::move(vk)) { From 8d28fd994c434531531e688709cfd7a310731d38 Mon Sep 17 00:00:00 2001 From: George Wright Date: Thu, 20 Feb 2020 10:56:20 -0800 Subject: [PATCH 3/3] formatting --- shell/common/shell_test_platform_view_vulkan.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index f8e1000c697bd..d6de169e7dc70 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -39,7 +39,8 @@ PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() { }; } -// TODO(gw280): This code was forked from vulkan_window.cc specifically for shell_test. +// TODO(gw280): This code was forked from vulkan_window.cc specifically for +// shell_test. // We need to merge this functionality back into //vulkan. // https://github.com/flutter/flutter/issues/51132 ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface(