diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc index 99d4da1cd2980..47c2fe9677371 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc @@ -727,6 +727,14 @@ void ContextVK::DisposeThreadLocalCachedResources() { command_pool_recycler_->Dispose(); } +void ContextVK::MarkFrameEnd() { + if (auto pipeline_library = GetPipelineLibrary()) { + PipelineLibraryVK::Cast(*pipeline_library).DidAcquireSurfaceFrame(); + } + DisposeThreadLocalCachedResources(); + GetResourceAllocator()->DebugTraceMemoryStatistics(); +} + const std::shared_ptr& ContextVK::GetYUVConversionLibrary() const { return yuv_conversion_library_; diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.h index 1486a93a676fd..da7de3cb083c9 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.h @@ -227,6 +227,12 @@ class ContextVK final : public Context, // |Context| void DisposeThreadLocalCachedResources() override; + /// @brief Perform frame-end maintenance: persist the pipeline cache to + /// disk periodically and dispose thread-local cached resources. + /// Called by SurfaceContextVK::MarkFrameEnd and directly by + /// embedder paths that bypass AcquireNextSurface. + void MarkFrameEnd(); + /// @brief Whether the Android Surface control based swapchain should be /// enabled bool GetShouldEnableSurfaceControlSwapchain() const; diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc index e14320f134d5f..aefbce6e67282 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc @@ -99,12 +99,7 @@ std::unique_ptr SurfaceContextVK::AcquireNextSurface() { } void SurfaceContextVK::MarkFrameEnd() { - if (auto pipeline_library = parent_->GetPipelineLibrary()) { - impeller::PipelineLibraryVK::Cast(*pipeline_library) - .DidAcquireSurfaceFrame(); - } - parent_->DisposeThreadLocalCachedResources(); - parent_->GetResourceAllocator()->DebugTraceMemoryStatistics(); + parent_->MarkFrameEnd(); } void SurfaceContextVK::UpdateSurfaceSize(const ISize& size) const { diff --git a/engine/src/flutter/shell/gpu/gpu_surface_vulkan_impeller.cc b/engine/src/flutter/shell/gpu/gpu_surface_vulkan_impeller.cc index e022e8965a8e7..0aa9b436cc0af 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_vulkan_impeller.cc +++ b/engine/src/flutter/shell/gpu/gpu_surface_vulkan_impeller.cc @@ -158,7 +158,11 @@ std::unique_ptr GPUSurfaceVulkanImpeller::AcquireFrame( impeller::ContextVK& context_vk = impeller::ContextVK::Cast(*impeller_context_); - context_vk.DisposeThreadLocalCachedResources(); + // The embedder path does not go through + // SurfaceContextVK::AcquireNextSurface (which calls MarkFrameEnd). + // Call MarkFrameEnd directly to ensure the Vulkan pipeline cache is + // periodically persisted to disk and thread-local resources are cleaned up. + context_vk.MarkFrameEnd(); impeller::vk::Image vk_image = impeller::vk::Image(reinterpret_cast(flutter_image.image)); diff --git a/engine/src/flutter/shell/platform/embedder/embedder.cc b/engine/src/flutter/shell/platform/embedder/embedder.cc index 41970ce55c6d6..fcd8b6c281b52 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder.cc @@ -683,7 +683,7 @@ InferVulkanPlatformViewCreationCallback( static_cast(config->vulkan.device), config->vulkan.queue_family_index, static_cast(config->vulkan.queue), vulkan_dispatch_table, - view_embedder); + view_embedder,config->vulkan.cache_path); return fml::MakeCopyable( [embedder_surface = std::move(embedder_surface), diff --git a/engine/src/flutter/shell/platform/embedder/embedder.h b/engine/src/flutter/shell/platform/embedder/embedder.h index 5475f275ed112..c88b158d588c1 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.h +++ b/engine/src/flutter/shell/platform/embedder/embedder.h @@ -1059,6 +1059,11 @@ typedef struct { /// that external texture details can be supplied to the engine for subsequent /// composition. FlutterVulkanTextureFrameCallback external_texture_frame_callback; + /// The path to the Vulkan pipeline cache data. + /// The string can be collected after the call to `FlutterEngineRun` returns. + /// The string must be NULL terminated. + /// If NULL, Impeller will not use the Vulkan pipeline cache. + const char* cache_path; } FlutterVulkanRendererConfig; typedef struct { diff --git a/engine/src/flutter/shell/platform/embedder/embedder_surface_vulkan_impeller.cc b/engine/src/flutter/shell/platform/embedder/embedder_surface_vulkan_impeller.cc index c19dfcae3fa9f..b3bceb398b8f5 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_surface_vulkan_impeller.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_surface_vulkan_impeller.cc @@ -29,7 +29,8 @@ EmbedderSurfaceVulkanImpeller::EmbedderSurfaceVulkanImpeller( uint32_t queue_family_index, VkQueue queue, const VulkanDispatchTable& vulkan_dispatch_table, - std::shared_ptr external_view_embedder) + std::shared_ptr external_view_embedder, + const char* cache_path) : vk_(fml::MakeRefCounted( vulkan_dispatch_table.get_instance_proc_address)), vulkan_dispatch_table_(vulkan_dispatch_table), @@ -54,6 +55,10 @@ EmbedderSurfaceVulkanImpeller::EmbedderSurfaceVulkanImpeller( settings.shader_libraries_data = shader_mappings; settings.proc_address_callback = vulkan_dispatch_table.get_instance_proc_address; + if (cache_path != nullptr) { + settings.cache_directory = + OpenDirectory(cache_path, false, fml::FilePermission::kReadWrite); + } impeller::ContextVK::EmbedderData data; data.instance = instance; diff --git a/engine/src/flutter/shell/platform/embedder/embedder_surface_vulkan_impeller.h b/engine/src/flutter/shell/platform/embedder/embedder_surface_vulkan_impeller.h index 961c3a34ee569..2e0691945a182 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_surface_vulkan_impeller.h +++ b/engine/src/flutter/shell/platform/embedder/embedder_surface_vulkan_impeller.h @@ -39,7 +39,8 @@ class EmbedderSurfaceVulkanImpeller final : public EmbedderSurface, uint32_t queue_family_index, VkQueue queue, const VulkanDispatchTable& vulkan_dispatch_table, - std::shared_ptr external_view_embedder); + std::shared_ptr external_view_embedder, + const char* cache_path); ~EmbedderSurfaceVulkanImpeller() override;