7#include <lib/async/cpp/task.h>
8#include <lib/async/default.h>
14#include "flutter/fml/trace_event.h"
15#include "flutter/vulkan/vulkan_skia_proc_table.h"
46 valid_ = Initialize();
49 FML_LOG(
FATAL) <<
"VulkanSurfaceProducer: Initialization failed";
57 vk_->QueueWaitIdle(logical_device_->GetQueueHandle()));
62bool VulkanSurfaceProducer::Initialize() {
63 vk_ = fml::MakeRefCounted<vulkan::VulkanProcTable>();
72 application_ = std::make_unique<vulkan::VulkanApplication>(
79 FML_LOG(
ERROR) <<
"VulkanSurfaceProducer: Instance proc addresses have not "
86 logical_device_ = application_->AcquireFirstCompatibleLogicalDevice();
88 if (logical_device_ ==
nullptr || !logical_device_->IsValid() ||
93 <<
"VulkanSurfaceProducer: Device proc addresses have not been set up.";
99 <<
"VulkanSurfaceProducer: Failed to acquire mandatory proc addresses.";
104 FML_LOG(
ERROR) <<
"VulkanSurfaceProducer: VulkanProcTable invalid";
110 if (getProc ==
nullptr) {
111 FML_LOG(
ERROR) <<
"VulkanSurfaceProducer: Failed to create skia getProc.";
116 if (!logical_device_->GetPhysicalDeviceFeatures(&features)) {
118 <<
"VulkanSurfaceProducer: Failed to get physical device features.";
124 application_->GetAPIVersion(), application_->GetInstance(),
125 logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(),
129 backend_context.
fInstance = application_->GetInstance();
130 backend_context.
fPhysicalDevice = logical_device_->GetPhysicalDeviceHandle();
131 backend_context.
fDevice = logical_device_->GetHandle();
132 backend_context.
fQueue = logical_device_->GetQueueHandle();
134 logical_device_->GetGraphicsQueueIndex();
137 backend_context.
fGetProc = std::move(getProc);
142 const char* device_extensions[] = {
145 const int device_extensions_count =
146 sizeof(device_extensions) /
sizeof(device_extensions[0]);
150 device_extensions_count, device_extensions);
157 if (context_ ==
nullptr) {
159 <<
"VulkanSurfaceProducer: Failed to create GrDirectContext.";
166 surface_pool_ = std::make_unique<VulkanSurfacePool>(*
this, context_);
172 std::vector<std::unique_ptr<SurfaceProducerSurface>> surfaces) {
173 TRACE_EVENT0(
"flutter",
"VulkanSurfaceProducer::SubmitSurfaces");
177 TRACE_EVENT0(
"flutter",
"GrDirectContext::flushAndSignalSemaphores");
181 if (!TransitionSurfacesToExternal(surfaces))
182 FML_LOG(
ERROR) <<
"TransitionSurfacesToExternal failed";
185 for (
auto&
surface : surfaces) {
186 SubmitSurface(std::move(
surface));
190 surface_pool_->AgeAndCollectOldBuffers();
194 constexpr auto kShouldShrinkThreshold = zx::msec(10 * 16.67);
195 async::PostDelayedTask(
196 async_get_default_dispatcher(),
197 [
self = weak_factory_.GetWeakPtr(), kShouldShrinkThreshold] {
201 auto time_since_last_produce =
202 async::Now(async_get_default_dispatcher()) -
203 self->last_produce_time_;
204 if (time_since_last_produce >= kShouldShrinkThreshold) {
205 self->surface_pool_->ShrinkToFit();
208 kShouldShrinkThreshold);
211bool VulkanSurfaceProducer::TransitionSurfacesToExternal(
212 const std::vector<std::unique_ptr<SurfaceProducerSurface>>& surfaces) {
213 for (
auto&
surface : surfaces) {
214 auto vk_surface =
static_cast<VulkanSurface*
>(
surface.get());
220 vk_surface->GetCommandBuffer(logical_device_->GetCommandPool());
221 if (!command_buffer->
Begin())
225 vk_surface->GetSkiaSurface().get(),
242#if defined(__aarch64__)
247 .srcQueueFamilyIndex = 0,
249 .image = vk_surface->GetVkImage(),
264 if (!command_buffer->
End())
267 if (!logical_device_->QueueSubmit(
268 {}, {}, {vk_surface->GetAcquireVkSemaphore()},
269 {command_buffer->Handle()}, vk_surface->GetCommandBufferFence()))
275std::unique_ptr<SurfaceProducerSurface> VulkanSurfaceProducer::ProduceSurface(
278 last_produce_time_ = async::Now(async_get_default_dispatcher());
279 return surface_pool_->AcquireSurface(
size);
282void VulkanSurfaceProducer::SubmitSurface(
283 std::unique_ptr<SurfaceProducerSurface>
surface) {
285 surface_pool_->SubmitSurface(std::move(
surface));
288std::unique_ptr<SurfaceProducerSurface>
289VulkanSurfaceProducer::ProduceOffscreenSurface(
const SkISize&
size) {
290 return surface_pool_->CreateSurface(
size);
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
void setResourceCacheLimit(size_t maxResourceBytes)
@ kFlushRead
back-end object is readable
static sk_sp< VulkanMemoryAllocator > Make(uint32_t vulkan_api_version, VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device, const fml::RefPtr< vulkan::VulkanProcTable > &vk, bool mustUseCoherentHostVisibleMemory)
void SubmitSurfaces(std::vector< std::unique_ptr< SurfaceProducerSurface > > surfaces) override
~VulkanSurfaceProducer() override
void init(VulkanGetProc, VkInstance, VkPhysicalDevice, uint32_t instanceExtensionCount, const char *const *instanceExtensions, uint32_t deviceExtensionCount, const char *const *deviceExtensions)
bool InsertPipelineBarrier(VkPipelineStageFlagBits src_stage_flags, VkPipelineStageFlagBits dest_stage_flags, uint32_t dependency_flags, uint32_t memory_barrier_count, const VkMemoryBarrier *memory_barriers, uint32_t buffer_memory_barrier_count, const VkBufferMemoryBarrier *buffer_memory_barriers, uint32_t image_memory_barrier_count, const VkImageMemoryBarrier *image_memory_barriers) const
bool AreDeviceProcsSetup() const
bool HasAcquiredMandatoryProcAddresses() const
bool AreInstanceProcsSetup() const
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
SK_API bool GetVkImageInfo(const GrBackendRenderTarget &, GrVkImageInfo *)
SK_API void SetVkImageLayout(GrBackendRenderTarget *, VkImageLayout)
SK_API sk_sp< GrDirectContext > MakeVulkan(const skgpu::VulkanBackendContext &, const GrContextOptions &)
SK_API GrBackendRenderTarget GetBackendRenderTarget(SkSurface *, BackendHandleAccess)
static const size_t kGrCacheMaxByteSize
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
GrVkGetProc CreateSkiaGetProc(const fml::RefPtr< vulkan::VulkanProcTable > &vk)
VkImageLayout fImageLayout
sk_sp< VulkanMemoryAllocator > fMemoryAllocator
const VkPhysicalDeviceFeatures * fDeviceFeatures
uint32_t fGraphicsQueueIndex
skgpu::VulkanGetProc fGetProc
VkPhysicalDevice fPhysicalDevice
const skgpu::VulkanExtensions * fVkExtensions
#define TRACE_EVENT0(category_group, name)
@ VK_IMAGE_LAYOUT_GENERAL
@ VK_IMAGE_ASPECT_COLOR_BIT
#define VK_MAKE_VERSION(major, minor, patch)
#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME
@ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
#define VK_QUEUE_FAMILY_EXTERNAL_KHR
#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME
@ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
@ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
@ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER
#define VK_CALL_LOG_ERROR(expression)