Flutter Engine
vulkan_surface.h
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 #pragma once
6 
7 #include <lib/async/cpp/wait.h>
8 #include <lib/ui/scenic/cpp/resources.h>
9 #include <lib/zx/event.h>
10 #include <lib/zx/vmo.h>
11 
12 #include <array>
13 #include <cstdint>
14 #include <memory>
15 
16 #include "flutter/fml/macros.h"
17 #include "flutter/vulkan/vulkan_command_buffer.h"
18 #include "flutter/vulkan/vulkan_handle.h"
19 #include "flutter/vulkan/vulkan_proc_table.h"
20 #include "flutter/vulkan/vulkan_provider.h"
21 #include "third_party/skia/include/core/SkSurface.h"
22 
23 #include "surface_producer.h"
24 
25 namespace flutter_runner {
26 
27 // A |VkImage| and its relevant metadata.
28 struct VulkanImage {
29  VulkanImage() = default;
30  VulkanImage(VulkanImage&&) = default;
31  VulkanImage& operator=(VulkanImage&&) = default;
32 
33  VkBufferCollectionImageCreateInfoFUCHSIAX vk_collection_image_create_info;
34  VkImageCreateInfo vk_image_create_info;
35  VkMemoryRequirements vk_memory_requirements;
37 
39 };
40 
41 class VulkanSurface final : public SurfaceProducerSurface {
42  public:
43  VulkanSurface(vulkan::VulkanProvider& vulkan_provider,
44  fuchsia::sysmem::AllocatorSyncPtr& sysmem_allocator,
45  fuchsia::ui::composition::AllocatorPtr& flatland_allocator,
46  sk_sp<GrDirectContext> context,
47  scenic::Session* session,
48  const SkISize& size,
49  uint32_t buffer_id);
50 
51  ~VulkanSurface() override;
52 
53  // |SurfaceProducerSurface|
54  size_t AdvanceAndGetAge() override;
55 
56  // |SurfaceProducerSurface|
57  bool FlushSessionAcquireAndReleaseEvents() override;
58 
59  // |SurfaceProducerSurface|
60  bool IsValid() const override;
61 
62  // |SurfaceProducerSurface|
63  SkISize GetSize() const override;
64 
65  // Note: It is safe for the caller to collect the surface in the
66  // |on_writes_committed| callback.
67  void SignalWritesFinished(
68  const std::function<void(void)>& on_writes_committed) override;
69 
70  // |SurfaceProducerSurface|
71  void SetImageId(uint32_t image_id) override;
72 
73  // |SurfaceProducerSurface|
74  uint32_t GetImageId() override;
75 
76  // |SurfaceProducerSurface|
77  sk_sp<SkSurface> GetSkiaSurface() const override;
78 
79  // |SurfaceProducerSurface|
80  fuchsia::ui::composition::BufferCollectionImportToken
81  GetBufferCollectionImportToken() override;
82 
83  // |SurfaceProducerSurface|
84  zx::event GetAcquireFence() override;
85 
86  // |SurfaceProducerSurface|
87  zx::event GetReleaseFence() override;
88 
89  // |SurfaceProducerSurface|
90  void SetReleaseImageCallback(
91  ReleaseImageCallback release_image_callback) override;
92 
94  return vulkan_image_.vk_image;
95  }
96 
98  return acquire_semaphore_;
99  }
100 
103  if (!command_buffer_)
104  command_buffer_ = std::make_unique<vulkan::VulkanCommandBuffer>(
105  vulkan_provider_.vk(), vulkan_provider_.vk_device(), pool);
106  return command_buffer_.get();
107  }
108 
110  return command_buffer_fence_;
111  }
112 
113  size_t GetAllocationSize() const { return vk_memory_info_.allocationSize; }
114 
116  return vulkan_image_.vk_memory_requirements.size;
117  }
118 
119  bool IsOversized() const {
120  return GetAllocationSize() > GetImageMemoryRequirementsSize();
121  }
122 
123  bool HasStableSizeHistory() const {
124  return std::equal(size_history_.begin() + 1, size_history_.end(),
125  size_history_.begin());
126  }
127 
128  private:
129  static constexpr int kSizeHistorySize = 4;
130 
131  void OnHandleReady(async_dispatcher_t* dispatcher,
132  async::WaitBase* wait,
133  zx_status_t status,
134  const zx_packet_signal_t* signal);
135 
136  bool AllocateDeviceMemory(
137  fuchsia::sysmem::AllocatorSyncPtr& sysmem_allocator,
138  fuchsia::ui::composition::AllocatorPtr& flatland_allocator,
139  sk_sp<GrDirectContext> context,
140  const SkISize& size,
141  uint32_t buffer_id);
142 
143  bool CreateVulkanImage(vulkan::VulkanProvider& vulkan_provider,
144  const SkISize& size,
145  VulkanImage* out_vulkan_image);
146 
147  bool SetupSkiaSurface(sk_sp<GrDirectContext> context,
148  const SkISize& size,
149  SkColorType color_type,
150  const VkImageCreateInfo& image_create_info,
151  const VkMemoryRequirements& memory_reqs);
152 
153  bool CreateFences();
154 
155  void PushSessionImageSetupOps(scenic::Session* session);
156 
157  void Reset();
158 
159  vulkan::VulkanHandle<VkSemaphore> SemaphoreFromEvent(
160  const zx::event& event) const;
161 
162  vulkan::VulkanProvider& vulkan_provider_;
163  scenic::Session* session_;
164  VulkanImage vulkan_image_;
166  VkMemoryAllocateInfo vk_memory_info_;
167  vulkan::VulkanHandle<VkFence> command_buffer_fence_;
168  sk_sp<SkSurface> sk_surface_;
169  uint32_t buffer_id_ = 0;
170  fuchsia::ui::composition::BufferCollectionImportToken import_token_;
171  uint32_t image_id_ = 0;
173  zx::event acquire_event_;
174  vulkan::VulkanHandle<VkSemaphore> acquire_semaphore_;
175  std::unique_ptr<vulkan::VulkanCommandBuffer> command_buffer_;
176  zx::event release_event_;
177  async::WaitMethod<VulkanSurface, &VulkanSurface::OnHandleReady> wait_;
178  std::function<void()> pending_on_writes_committed_;
179  std::array<SkISize, kSizeHistorySize> size_history_;
180  int size_history_index_ = 0;
181  size_t age_ = 0;
182  bool valid_ = false;
183  ReleaseImageCallback release_image_callback_;
184 
186 };
187 
188 } // namespace flutter_runner
VkImageCreateInfo vk_image_create_info
const vulkan::VulkanHandle< VkSemaphore > & GetAcquireVkSemaphore()
const vulkan::VulkanHandle< VkImage > & GetVkImage()
uint32_t color_type
Dart_NativeFunction function
Definition: fuchsia.cc:51
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
vulkan::VulkanCommandBuffer * GetCommandBuffer(const vulkan::VulkanHandle< VkCommandPool > &pool)
FlKeyEvent * event
VkMemoryRequirements vk_memory_requirements
static bool IsValid(double value)
FML_DISALLOW_COPY_AND_ASSIGN(VulkanImage)
VulkanImage & operator=(VulkanImage &&)=default
std::function< void()> ReleaseImageCallback
VkBufferCollectionImageCreateInfoFUCHSIAX vk_collection_image_create_info
size_t GetImageMemoryRequirementsSize() const
const vulkan::VulkanHandle< VkFence > & GetCommandBufferFence()
vulkan::VulkanHandle< VkImage > vk_image