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"
41constexpr size_t kGrCacheMaxByteSize = 1024 * 600 * 12 * 4;
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>();
65 std::vector<std::string> extensions = {
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.";
115 uint32_t skia_features = 0;
116 if (!logical_device_->GetPhysicalDeviceFeaturesSkia(&skia_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.
fFeatures = skia_features;
138 backend_context.
fGetProc = std::move(getProc);
144 const char* device_extensions[] = {
147 const int device_extensions_count =
148 sizeof(device_extensions) /
sizeof(device_extensions[0]);
152 device_extensions_count, device_extensions);
159 if (context_ ==
nullptr) {
161 <<
"VulkanSurfaceProducer: Failed to create GrDirectContext.";
168 surface_pool_ = std::make_unique<VulkanSurfacePool>(*
this, context_);
174 std::vector<std::unique_ptr<SurfaceProducerSurface>> surfaces) {
175 TRACE_EVENT0(
"flutter",
"VulkanSurfaceProducer::SubmitSurfaces");
179 TRACE_EVENT0(
"flutter",
"GrDirectContext::flushAndSignalSemaphores");
183 if (!TransitionSurfacesToExternal(surfaces))
184 FML_LOG(
ERROR) <<
"TransitionSurfacesToExternal failed";
187 for (
auto&
surface : surfaces) {
188 SubmitSurface(std::move(
surface));
192 surface_pool_->AgeAndCollectOldBuffers();
196 constexpr auto kShouldShrinkThreshold = zx::msec(10 * 16.67);
197 async::PostDelayedTask(
198 async_get_default_dispatcher(),
199 [
self = weak_factory_.GetWeakPtr(), kShouldShrinkThreshold] {
203 auto time_since_last_produce =
204 async::Now(async_get_default_dispatcher()) -
205 self->last_produce_time_;
206 if (time_since_last_produce >= kShouldShrinkThreshold) {
207 self->surface_pool_->ShrinkToFit();
210 kShouldShrinkThreshold);
213bool VulkanSurfaceProducer::TransitionSurfacesToExternal(
214 const std::vector<std::unique_ptr<SurfaceProducerSurface>>& surfaces) {
215 for (
auto&
surface : surfaces) {
216 auto vk_surface =
static_cast<VulkanSurface*
>(
surface.get());
222 vk_surface->GetCommandBuffer(logical_device_->GetCommandPool());
223 if (!command_buffer->
Begin())
227 vk_surface->GetSkiaSurface().get(),
228 SkSurfaces::BackendHandleAccess::kFlushRead);
244#if defined(__aarch64__)
249 .srcQueueFamilyIndex = 0,
251 .image = vk_surface->GetVkImage(),
266 if (!command_buffer->
End())
269 if (!logical_device_->QueueSubmit(
270 {}, {}, {vk_surface->GetAcquireVkSemaphore()},
271 {command_buffer->Handle()}, vk_surface->GetCommandBufferFence()))
277std::unique_ptr<SurfaceProducerSurface> VulkanSurfaceProducer::ProduceSurface(
280 last_produce_time_ = async::Now(async_get_default_dispatcher());
281 return surface_pool_->AcquireSurface(size);
284void VulkanSurfaceProducer::SubmitSurface(
285 std::unique_ptr<SurfaceProducerSurface>
surface) {
287 surface_pool_->SubmitSurface(std::move(
surface));
290std::unique_ptr<SurfaceProducerSurface>
291VulkanSurfaceProducer::ProduceOffscreenSurface(
const SkISize& size) {
292 return surface_pool_->CreateSurface(size);
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
void setResourceCacheLimit(size_t maxResourceBytes)
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 GrVkBackendContext &, const GrContextOptions &)
SK_API GrBackendRenderTarget GetBackendRenderTarget(SkSurface *, BackendHandleAccess)
GrVkGetProc CreateSkiaGetProc(const fml::RefPtr< vulkan::VulkanProcTable > &vk)
Enable fReduceOpsTaskSplitting
const skgpu::VulkanExtensions * fVkExtensions
bool fOwnsInstanceAndDevice
VkPhysicalDevice fPhysicalDevice
uint32_t fGraphicsQueueIndex
skgpu::VulkanGetProc fGetProc
sk_sp< skgpu::VulkanMemoryAllocator > fMemoryAllocator
VkImageLayout fImageLayout
#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)