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 <memory>
14 
15 #include "flutter/flow/raster_cache_key.h"
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 namespace flutter_runner {
24 
26  public:
27  virtual ~SurfaceProducerSurface() = default;
28 
29  virtual size_t AdvanceAndGetAge() = 0;
30 
31  virtual bool FlushSessionAcquireAndReleaseEvents() = 0;
32 
33  virtual bool IsValid() const = 0;
34 
35  virtual SkISize GetSize() const = 0;
36 
37  virtual void SignalWritesFinished(
38  const std::function<void(void)>& on_writes_committed) = 0;
39 
40  virtual scenic::Image* GetImage() = 0;
41 
42  virtual sk_sp<SkSurface> GetSkiaSurface() const = 0;
43 };
44 
46  public:
47  virtual ~SurfaceProducer() = default;
48 
49  virtual std::unique_ptr<SurfaceProducerSurface> ProduceSurface(
50  const SkISize& size) = 0;
51 
52  virtual void SubmitSurface(
53  std::unique_ptr<SurfaceProducerSurface> surface) = 0;
54 };
55 
56 // A |VkImage| and its relevant metadata.
57 struct VulkanImage {
58  VulkanImage() = default;
59  VulkanImage(VulkanImage&&) = default;
60  VulkanImage& operator=(VulkanImage&&) = default;
61 
62  VkExternalMemoryImageCreateInfo vk_external_image_create_info;
63  VkImageCreateInfo vk_image_create_info;
64  VkMemoryRequirements vk_memory_requirements;
66 
68 };
69 
70 // Create a new |VulkanImage| of size |size|, stored in
71 // |out_vulkan_image|. Returns whether creation of the |VkImage| was
72 // successful.
73 bool CreateVulkanImage(vulkan::VulkanProvider& vulkan_provider,
74  const SkISize& size,
75  VulkanImage* out_vulkan_image);
76 
77 class VulkanSurface final : public SurfaceProducerSurface {
78  public:
79  VulkanSurface(vulkan::VulkanProvider& vulkan_provider,
80  sk_sp<GrDirectContext> context,
81  scenic::Session* session,
82  const SkISize& size);
83 
84  ~VulkanSurface() override;
85 
86  // |SurfaceProducerSurface|
87  size_t AdvanceAndGetAge() override;
88 
89  // |SurfaceProducerSurface|
91 
92  // |SurfaceProducerSurface|
93  bool IsValid() const override;
94 
95  // |SurfaceProducerSurface|
96  SkISize GetSize() const override;
97 
98  // Note: It is safe for the caller to collect the surface in the
99  // |on_writes_committed| callback.
101  const std::function<void(void)>& on_writes_committed) override;
102 
103  // |SurfaceProducerSurface|
104  scenic::Image* GetImage() override;
105 
106  // |SurfaceProducerSurface|
107  sk_sp<SkSurface> GetSkiaSurface() const override;
108 
110  return vulkan_image_.vk_image;
111  }
112 
114  return acquire_semaphore_;
115  }
116 
119  if (!command_buffer_)
120  command_buffer_ = std::make_unique<vulkan::VulkanCommandBuffer>(
121  vulkan_provider_.vk(), vulkan_provider_.vk_device(), pool);
122  return command_buffer_.get();
123  }
124 
126  return command_buffer_fence_;
127  }
128 
129  size_t GetAllocationSize() const { return vk_memory_info_.allocationSize; }
130 
132  return vulkan_image_.vk_memory_requirements.size;
133  }
134 
135  bool IsOversized() const {
136  return GetAllocationSize() > GetImageMemoryRequirementsSize();
137  }
138 
139  bool HasStableSizeHistory() const {
140  return std::equal(size_history_.begin() + 1, size_history_.end(),
141  size_history_.begin());
142  }
143 
144  // Bind |vulkan_image| to |vk_memory_| and create a new skia surface,
145  // replacing the previous |vk_image_|. |vulkan_image| MUST require less
146  // than or equal the amount of memory contained in |vk_memory_|. Returns
147  // whether the swap was successful. The |VulkanSurface| will become invalid
148  // if the swap was not successful.
149  bool BindToImage(sk_sp<GrDirectContext> context, VulkanImage vulkan_image);
150 
151  private:
152  static constexpr int kSizeHistorySize = 4;
153 
154  void OnHandleReady(async_dispatcher_t* dispatcher,
155  async::WaitBase* wait,
156  zx_status_t status,
157  const zx_packet_signal_t* signal);
158 
159  bool AllocateDeviceMemory(sk_sp<GrDirectContext> context,
160  const SkISize& size,
161  zx::vmo& exported_vmo);
162 
163  bool SetupSkiaSurface(sk_sp<GrDirectContext> context,
164  const SkISize& size,
165  SkColorType color_type,
166  const VkImageCreateInfo& image_create_info,
167  const VkMemoryRequirements& memory_reqs);
168 
169  bool CreateFences();
170 
171  bool PushSessionImageSetupOps(scenic::Session* session);
172 
173  void Reset();
174 
175  vulkan::VulkanHandle<VkSemaphore> SemaphoreFromEvent(
176  const zx::event& event) const;
177 
178  vulkan::VulkanProvider& vulkan_provider_;
179  scenic::Session* session_;
180  VulkanImage vulkan_image_;
182  VkMemoryAllocateInfo vk_memory_info_;
183  vulkan::VulkanHandle<VkFence> command_buffer_fence_;
184  sk_sp<SkSurface> sk_surface_;
185  // TODO: Don't heap allocate this once SCN-268 is resolved.
186  std::unique_ptr<scenic::Memory> scenic_memory_;
187  std::unique_ptr<scenic::Image> session_image_;
188  zx::event acquire_event_;
189  vulkan::VulkanHandle<VkSemaphore> acquire_semaphore_;
190  std::unique_ptr<vulkan::VulkanCommandBuffer> command_buffer_;
191  zx::event release_event_;
192  async::WaitMethod<VulkanSurface, &VulkanSurface::OnHandleReady> wait_;
193  std::function<void()> pending_on_writes_committed_;
194  std::array<SkISize, kSizeHistorySize> size_history_;
195  int size_history_index_ = 0;
196  size_t age_ = 0;
197  bool valid_ = false;
198 
200 };
201 
202 } // namespace flutter_runner
VkImageCreateInfo vk_image_create_info
const vulkan::VulkanHandle< VkSemaphore > & GetAcquireVkSemaphore()
virtual bool FlushSessionAcquireAndReleaseEvents()=0
virtual scenic::Image * GetImage()=0
const vulkan::VulkanHandle< VkImage > & GetVkImage()
CanvasImage Image
Definition: image.cc:15
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)
VkMemoryRequirements vk_memory_requirements
bool CreateVulkanImage(vulkan::VulkanProvider &vulkan_provider, const SkISize &size, VulkanImage *out_vulkan_image)
virtual SkISize GetSize() const =0
GdkEventButton * event
Definition: fl_view.cc:62
VkExternalMemoryImageCreateInfo vk_external_image_create_info
virtual sk_sp< SkSurface > GetSkiaSurface() const =0
size_t GetImageMemoryRequirementsSize() const
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:27
const vulkan::VulkanHandle< VkFence > & GetCommandBufferFence()
virtual void SignalWritesFinished(const std::function< void(void)> &on_writes_committed)=0
vulkan::VulkanHandle< VkImage > vk_image