Flutter Engine
shell_test_platform_view_vulkan.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/shell/common/shell_test_platform_view_vulkan.h"
6 
7 #include "flutter/common/graphics/persistent_cache.h"
8 #include "flutter/shell/common/context_options.h"
9 #include "flutter/vulkan/vulkan_utilities.h"
10 
11 namespace flutter {
12 namespace testing {
13 
15  PlatformView::Delegate& delegate,
16  TaskRunners task_runners,
17  std::shared_ptr<ShellTestVsyncClock> vsync_clock,
18  CreateVsyncWaiter create_vsync_waiter,
19  std::shared_ptr<ShellTestExternalViewEmbedder>
20  shell_test_external_view_embedder)
21  : ShellTestPlatformView(delegate, std::move(task_runners)),
22  create_vsync_waiter_(std::move(create_vsync_waiter)),
23  vsync_clock_(vsync_clock),
24  proc_table_(fml::MakeRefCounted<vulkan::VulkanProcTable>()),
25  shell_test_external_view_embedder_(shell_test_external_view_embedder) {}
26 
28 
29 std::unique_ptr<VsyncWaiter> ShellTestPlatformViewVulkan::CreateVSyncWaiter() {
30  return create_vsync_waiter_();
31 }
32 
34  vsync_clock_->SimulateVSync();
35 }
36 
37 // |PlatformView|
38 std::unique_ptr<Surface> ShellTestPlatformViewVulkan::CreateRenderingSurface() {
39  return std::make_unique<OffScreenSurface>(proc_table_,
40  shell_test_external_view_embedder_);
41 }
42 
43 // |PlatformView|
44 std::shared_ptr<ExternalViewEmbedder>
45 ShellTestPlatformViewVulkan::CreateExternalViewEmbedder() {
46  return shell_test_external_view_embedder_;
47 }
48 
49 // |PlatformView|
50 PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() {
51  return [](DefaultPointerDataDispatcher::Delegate& delegate) {
52  return std::make_unique<SmoothPointerDataDispatcher>(delegate);
53  };
54 }
55 
56 // TODO(gw280): This code was forked from vulkan_window.cc specifically for
57 // shell_test.
58 // We need to merge this functionality back into //vulkan.
59 // https://github.com/flutter/flutter/issues/51132
60 ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface(
62  std::shared_ptr<ShellTestExternalViewEmbedder>
63  shell_test_external_view_embedder)
64  : valid_(false),
65  vk_(std::move(vk)),
66  shell_test_external_view_embedder_(shell_test_external_view_embedder) {
67  if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) {
68  FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses.";
69  return;
70  }
71 
72  // Create the application instance.
73  std::vector<std::string> extensions = {
74  VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
75  };
76 
77  application_ = std::make_unique<vulkan::VulkanApplication>(
78  *vk_, "FlutterTest", std::move(extensions), VK_MAKE_VERSION(1, 0, 0),
79  VK_MAKE_VERSION(1, 1, 0), true);
80 
81  if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) {
82  // Make certain the application instance was created and it set up the
83  // instance proc table entries.
84  FML_DLOG(ERROR) << "Instance proc addresses have not been set up.";
85  return;
86  }
87 
88  // Create the device.
89 
90  logical_device_ = application_->AcquireFirstCompatibleLogicalDevice();
91 
92  if (logical_device_ == nullptr || !logical_device_->IsValid() ||
93  !vk_->AreDeviceProcsSetup()) {
94  // Make certain the device was created and it set up the device proc table
95  // entries.
96  FML_DLOG(ERROR) << "Device proc addresses have not been set up.";
97  return;
98  }
99 
100  // Create the Skia GrContext.
101  if (!CreateSkiaGrContext()) {
102  FML_DLOG(ERROR) << "Could not create Skia context.";
103  return;
104  }
105 
106  valid_ = true;
107 }
108 
109 bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaGrContext() {
110  GrVkBackendContext backend_context;
111 
112  if (!CreateSkiaBackendContext(&backend_context)) {
113  FML_DLOG(ERROR) << "Could not create Skia backend context.";
114  return false;
115  }
116 
117  const auto options =
118  MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kVulkan);
119 
120  sk_sp<GrDirectContext> context =
121  GrDirectContext::MakeVulkan(backend_context, options);
122 
123  if (context == nullptr) {
124  FML_DLOG(ERROR) << "Failed to create GrDirectContext";
125  return false;
126  }
127 
128  context->setResourceCacheLimits(vulkan::kGrCacheMaxCount,
130 
131  context_ = context;
132 
133  return true;
134 }
135 
136 bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaBackendContext(
137  GrVkBackendContext* context) {
138  auto getProc = vk_->CreateSkiaGetProc();
139 
140  if (getProc == nullptr) {
141  FML_DLOG(ERROR) << "GetProcAddress is null";
142  return false;
143  }
144 
145  uint32_t skia_features = 0;
146  if (!logical_device_->GetPhysicalDeviceFeaturesSkia(&skia_features)) {
147  FML_DLOG(ERROR) << "Failed to get Physical Device features";
148  return false;
149  }
150 
151  context->fInstance = application_->GetInstance();
152  context->fPhysicalDevice = logical_device_->GetPhysicalDeviceHandle();
153  context->fDevice = logical_device_->GetHandle();
154  context->fQueue = logical_device_->GetQueueHandle();
155  context->fGraphicsQueueIndex = logical_device_->GetGraphicsQueueIndex();
156  context->fMinAPIVersion = application_->GetAPIVersion();
157  context->fMaxAPIVersion = application_->GetAPIVersion();
158  context->fFeatures = skia_features;
159  context->fGetProc = std::move(getProc);
160  context->fOwnsInstanceAndDevice = false;
161  return true;
162 }
163 
164 ShellTestPlatformViewVulkan::OffScreenSurface::~OffScreenSurface() {}
165 
167  return valid_;
168 }
169 
170 std::unique_ptr<SurfaceFrame>
171 ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame(
172  const SkISize& size) {
173  auto image_info = SkImageInfo::Make(size, SkColorType::kRGBA_8888_SkColorType,
174  SkAlphaType::kOpaque_SkAlphaType);
175  auto surface = SkSurface::MakeRenderTarget(context_.get(), SkBudgeted::kNo,
176  image_info, 0, nullptr);
178  SkCanvas* canvas) -> bool {
179  canvas->flush();
180  return true;
181  };
182 
183  SurfaceFrame::FramebufferInfo framebuffer_info;
184  framebuffer_info.supports_readback = true;
185 
186  return std::make_unique<SurfaceFrame>(
187  std::move(surface), std::move(framebuffer_info), std::move(callback));
188 }
189 
190 GrDirectContext* ShellTestPlatformViewVulkan::OffScreenSurface::GetContext() {
191  return context_.get();
192 }
193 
194 SkMatrix ShellTestPlatformViewVulkan::OffScreenSurface::GetRootTransformation()
195  const {
196  SkMatrix matrix;
197  matrix.reset();
198  return matrix;
199 }
200 
201 } // namespace testing
202 } // namespace flutter
std::function< bool(const SurfaceFrame &surface_frame, SkCanvas *canvas)> SubmitCallback
Definition: surface_frame.h:24
static const size_t kGrCacheMaxByteSize
ShellTestPlatformViewVulkan(PlatformView::Delegate &delegate, TaskRunners task_runners, std::shared_ptr< ShellTestVsyncClock > vsync_clock, CreateVsyncWaiter create_vsync_waiter, std::shared_ptr< ShellTestExternalViewEmbedder > shell_test_external_view_embedder)
Definition: ref_ptr.h:255
The interface for Engine to implement.
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
std::function< std::unique_ptr< PointerDataDispatcher >(PointerDataDispatcher::Delegate &)> PointerDataDispatcherMaker
Signature for constructing PointerDataDispatcher.
FlKeyEvent FlKeyResponderAsyncCallback callback
Definition: ascii_trie.cc:9
std::function< std::unique_ptr< VsyncWaiter >()> CreateVsyncWaiter
static bool IsValid(double value)
RefPtr< T > MakeRefCounted(Args &&... args)
Definition: ref_ptr.h:247
The context is used to render to a texture or renderbuffer.
static const int kGrCacheMaxCount
#define FML_DLOG(severity)
Definition: logging.h:85
Used to forward events from the platform view to interested subsystems. This forwarding is done by th...
Definition: platform_view.h:54
GrContextOptions MakeDefaultContextOptions(ContextType type, std::optional< GrBackendApi > api)
Initializes GrContextOptions with values suitable for Flutter. The options can be further tweaked bef...