diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index a1989101ea127..c2ee613eefb34 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1489,6 +1489,7 @@ ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/descriptor_pool_vk.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/device_buffer_vk.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/device_buffer_vk.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/device_holder.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/fence_waiter_vk.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/fence_waiter_vk.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/formats_vk.cc + ../../../flutter/LICENSE @@ -4090,6 +4091,7 @@ FILE: ../../../flutter/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc FILE: ../../../flutter/impeller/renderer/backend/vulkan/descriptor_pool_vk.h FILE: ../../../flutter/impeller/renderer/backend/vulkan/device_buffer_vk.cc FILE: ../../../flutter/impeller/renderer/backend/vulkan/device_buffer_vk.h +FILE: ../../../flutter/impeller/renderer/backend/vulkan/device_holder.h FILE: ../../../flutter/impeller/renderer/backend/vulkan/fence_waiter_vk.cc FILE: ../../../flutter/impeller/renderer/backend/vulkan/fence_waiter_vk.h FILE: ../../../flutter/impeller/renderer/backend/vulkan/formats_vk.cc diff --git a/impeller/renderer/backend/gles/context_gles.h b/impeller/renderer/backend/gles/context_gles.h index 5387f9aa908e3..2faea35232a04 100644 --- a/impeller/renderer/backend/gles/context_gles.h +++ b/impeller/renderer/backend/gles/context_gles.h @@ -18,7 +18,8 @@ namespace impeller { class ContextGLES final : public Context, - public BackendCast { + public BackendCast, + public std::enable_shared_from_this { public: static std::shared_ptr Create( std::unique_ptr gl, diff --git a/impeller/renderer/backend/metal/context_mtl.h b/impeller/renderer/backend/metal/context_mtl.h index c0e86de607526..f6a5bfd25232e 100644 --- a/impeller/renderer/backend/metal/context_mtl.h +++ b/impeller/renderer/backend/metal/context_mtl.h @@ -22,7 +22,8 @@ namespace impeller { class ContextMTL final : public Context, - public BackendCast { + public BackendCast, + public std::enable_shared_from_this { public: static std::shared_ptr Create( const std::vector& shader_library_paths); diff --git a/impeller/renderer/backend/metal/surface_mtl.mm b/impeller/renderer/backend/metal/surface_mtl.mm index 4bf510cdfe304..55e88039f1c51 100644 --- a/impeller/renderer/backend/metal/surface_mtl.mm +++ b/impeller/renderer/backend/metal/surface_mtl.mm @@ -112,9 +112,9 @@ render_target_desc.SetColorAttachment(color0, 0u); // The constructor is private. So make_unique may not be used. - return std::unique_ptr( - new SurfaceMTL(context->weak_from_this(), render_target_desc, resolve_tex, - drawable, requires_blit, clip_rect)); + return std::unique_ptr(new SurfaceMTL(context, render_target_desc, + resolve_tex, drawable, + requires_blit, clip_rect)); } SurfaceMTL::SurfaceMTL(const std::weak_ptr& context, diff --git a/impeller/renderer/backend/vulkan/blit_command_vk_unittests.cc b/impeller/renderer/backend/vulkan/blit_command_vk_unittests.cc index a6f871d64c694..63975c955e8dd 100644 --- a/impeller/renderer/backend/vulkan/blit_command_vk_unittests.cc +++ b/impeller/renderer/backend/vulkan/blit_command_vk_unittests.cc @@ -13,8 +13,8 @@ namespace testing { TEST(BlitCommandVkTest, BlitCopyTextureToTextureCommandVK) { auto context = CreateMockVulkanContext(); auto pool = CommandPoolVK::GetThreadLocal(context.get()); - CommandEncoderVK encoder(context->GetDevice(), context->GetGraphicsQueue(), - pool, context->GetFenceWaiter()); + CommandEncoderVK encoder(context, context->GetGraphicsQueue(), pool, + context->GetFenceWaiter()); BlitCopyTextureToTextureCommandVK cmd; cmd.source = context->GetResourceAllocator()->CreateTexture({ .size = ISize(100, 100), @@ -31,8 +31,8 @@ TEST(BlitCommandVkTest, BlitCopyTextureToTextureCommandVK) { TEST(BlitCommandVkTest, BlitCopyTextureToBufferCommandVK) { auto context = CreateMockVulkanContext(); auto pool = CommandPoolVK::GetThreadLocal(context.get()); - CommandEncoderVK encoder(context->GetDevice(), context->GetGraphicsQueue(), - pool, context->GetFenceWaiter()); + CommandEncoderVK encoder(context, context->GetGraphicsQueue(), pool, + context->GetFenceWaiter()); BlitCopyTextureToBufferCommandVK cmd; cmd.source = context->GetResourceAllocator()->CreateTexture({ .size = ISize(100, 100), @@ -49,8 +49,8 @@ TEST(BlitCommandVkTest, BlitCopyTextureToBufferCommandVK) { TEST(BlitCommandVkTest, BlitGenerateMipmapCommandVK) { auto context = CreateMockVulkanContext(); auto pool = CommandPoolVK::GetThreadLocal(context.get()); - CommandEncoderVK encoder(context->GetDevice(), context->GetGraphicsQueue(), - pool, context->GetFenceWaiter()); + CommandEncoderVK encoder(context, context->GetGraphicsQueue(), pool, + context->GetFenceWaiter()); BlitGenerateMipmapCommandVK cmd; cmd.texture = context->GetResourceAllocator()->CreateTexture({ .size = ISize(100, 100), diff --git a/impeller/renderer/backend/vulkan/command_encoder_vk.cc b/impeller/renderer/backend/vulkan/command_encoder_vk.cc index fd6cbec90be2a..6c60c37834ea6 100644 --- a/impeller/renderer/backend/vulkan/command_encoder_vk.cc +++ b/impeller/renderer/backend/vulkan/command_encoder_vk.cc @@ -14,9 +14,9 @@ namespace impeller { class TrackedObjectsVK { public: - explicit TrackedObjectsVK(const vk::Device& device, + explicit TrackedObjectsVK(std::weak_ptr device_holder, const std::shared_ptr& pool) - : desc_pool_(device) { + : desc_pool_(device_holder) { if (!pool) { return; } @@ -95,12 +95,14 @@ class TrackedObjectsVK { FML_DISALLOW_COPY_AND_ASSIGN(TrackedObjectsVK); }; -CommandEncoderVK::CommandEncoderVK(vk::Device device, - const std::shared_ptr& queue, - const std::shared_ptr& pool, - std::shared_ptr fence_waiter) +CommandEncoderVK::CommandEncoderVK( + std::weak_ptr device_holder, + const std::shared_ptr& queue, + const std::shared_ptr& pool, + std::shared_ptr fence_waiter) : fence_waiter_(std::move(fence_waiter)), - tracked_objects_(std::make_shared(device, pool)) { + tracked_objects_( + std::make_shared(device_holder, pool)) { if (!fence_waiter_ || !tracked_objects_->IsValid() || !queue) { return; } @@ -111,7 +113,7 @@ CommandEncoderVK::CommandEncoderVK(vk::Device device, VALIDATION_LOG << "Could not begin command buffer."; return; } - device_ = device; + device_holder_ = device_holder; queue_ = queue; is_valid_ = true; } @@ -137,7 +139,11 @@ bool CommandEncoderVK::Submit() { if (command_buffer.end() != vk::Result::eSuccess) { return false; } - auto [fence_result, fence] = device_.createFenceUnique({}); + std::shared_ptr strong_device = device_holder_.lock(); + if (!strong_device) { + return false; + } + auto [fence_result, fence] = strong_device->GetDevice().createFenceUnique({}); if (fence_result != vk::Result::eSuccess) { return false; } @@ -166,7 +172,7 @@ void CommandEncoderVK::Reset() { tracked_objects_.reset(); queue_ = nullptr; - device_ = nullptr; + device_holder_ = {}; is_valid_ = false; } diff --git a/impeller/renderer/backend/vulkan/command_encoder_vk.h b/impeller/renderer/backend/vulkan/command_encoder_vk.h index 9a4581cdf9c9b..d160385472702 100644 --- a/impeller/renderer/backend/vulkan/command_encoder_vk.h +++ b/impeller/renderer/backend/vulkan/command_encoder_vk.h @@ -10,6 +10,7 @@ #include "flutter/fml/macros.h" #include "impeller/renderer/backend/vulkan/command_pool_vk.h" #include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h" +#include "impeller/renderer/backend/vulkan/device_holder.h" #include "impeller/renderer/backend/vulkan/queue_vk.h" #include "impeller/renderer/backend/vulkan/shared_object_vk.h" #include "impeller/renderer/backend/vulkan/vk.h" @@ -69,13 +70,13 @@ class CommandEncoderVK { friend class ::impeller::testing:: BlitCommandVkTest_BlitGenerateMipmapCommandVK_Test; - vk::Device device_ = {}; + std::weak_ptr device_holder_; std::shared_ptr queue_; std::shared_ptr fence_waiter_; std::shared_ptr tracked_objects_; bool is_valid_ = false; - CommandEncoderVK(vk::Device device, + CommandEncoderVK(std::weak_ptr device_holder, const std::shared_ptr& queue, const std::shared_ptr& pool, std::shared_ptr fence_waiter); diff --git a/impeller/renderer/backend/vulkan/command_pool_vk.cc b/impeller/renderer/backend/vulkan/command_pool_vk.cc index 25b8a86eba563..5949ad84c4094 100644 --- a/impeller/renderer/backend/vulkan/command_pool_vk.cc +++ b/impeller/renderer/backend/vulkan/command_pool_vk.cc @@ -79,7 +79,7 @@ CommandPoolVK::CommandPoolVK(const ContextVK* context) return; } - device_ = context->GetDevice(); + device_holder_ = context->weak_from_this(); graphics_pool_ = std::move(pool.value); is_valid_ = true; } @@ -102,6 +102,10 @@ vk::CommandPool CommandPoolVK::GetGraphicsCommandPool() const { } vk::UniqueCommandBuffer CommandPoolVK::CreateGraphicsCommandBuffer() { + std::shared_ptr strong_device = device_holder_.lock(); + if (!strong_device) { + return {}; + } if (std::this_thread::get_id() != owner_id_) { return {}; } @@ -113,7 +117,8 @@ vk::UniqueCommandBuffer CommandPoolVK::CreateGraphicsCommandBuffer() { alloc_info.commandPool = graphics_pool_.get(); alloc_info.commandBufferCount = 1u; alloc_info.level = vk::CommandBufferLevel::ePrimary; - auto [result, buffers] = device_.allocateCommandBuffersUnique(alloc_info); + auto [result, buffers] = + strong_device->GetDevice().allocateCommandBuffersUnique(alloc_info); if (result != vk::Result::eSuccess) { return {}; } diff --git a/impeller/renderer/backend/vulkan/command_pool_vk.h b/impeller/renderer/backend/vulkan/command_pool_vk.h index 7399e22686075..a059da8390419 100644 --- a/impeller/renderer/backend/vulkan/command_pool_vk.h +++ b/impeller/renderer/backend/vulkan/command_pool_vk.h @@ -10,6 +10,7 @@ #include "flutter/fml/macros.h" #include "impeller/base/thread.h" +#include "impeller/renderer/backend/vulkan/device_holder.h" #include "impeller/renderer/backend/vulkan/shared_object_vk.h" #include "impeller/renderer/backend/vulkan/vk.h" @@ -38,7 +39,7 @@ class CommandPoolVK { private: const std::thread::id owner_id_; - vk::Device device_ = {}; + std::weak_ptr device_holder_; vk::UniqueCommandPool graphics_pool_; Mutex buffers_to_collect_mutex_; std::set> buffers_to_collect_ diff --git a/impeller/renderer/backend/vulkan/context_vk.cc b/impeller/renderer/backend/vulkan/context_vk.cc index d41ccd0a5fa5a..7d77740694934 100644 --- a/impeller/renderer/backend/vulkan/context_vk.cc +++ b/impeller/renderer/backend/vulkan/context_vk.cc @@ -273,11 +273,12 @@ void ContextVK::Setup(Settings settings) { device_info.setPEnabledFeatures(&required_features.value()); // Device layers are deprecated and ignored. - auto device = physical_device->createDeviceUnique(device_info); - if (device.result != vk::Result::eSuccess) { + auto device_result = physical_device->createDeviceUnique(device_info); + if (device_result.result != vk::Result::eSuccess) { VALIDATION_LOG << "Could not create logical device."; return; } + vk::UniqueDevice device = std::move(device_result.value); if (!caps->SetDevice(physical_device.value())) { VALIDATION_LOG << "Capabilities could not be updated."; @@ -291,7 +292,7 @@ void ContextVK::Setup(Settings settings) { weak_from_this(), // application_info.apiVersion, // physical_device.value(), // - device.value.get(), // + device.get(), // instance.value.get(), // dispatcher.vkGetInstanceProcAddr, // dispatcher.vkGetDeviceProcAddr // @@ -306,7 +307,8 @@ void ContextVK::Setup(Settings settings) { /// Setup the pipeline library. /// auto pipeline_library = std::shared_ptr( - new PipelineLibraryVK(device.value.get(), // + new PipelineLibraryVK(weak_from_this(), // + device.get(), // caps, // std::move(settings.cache_directory), // settings.worker_task_runner // @@ -317,11 +319,11 @@ void ContextVK::Setup(Settings settings) { return; } - auto sampler_library = std::shared_ptr( - new SamplerLibraryVK(device.value.get())); + auto sampler_library = + std::shared_ptr(new SamplerLibraryVK(device.get())); auto shader_library = std::shared_ptr( - new ShaderLibraryVK(device.value.get(), // + new ShaderLibraryVK(device.get(), // settings.shader_libraries_data) // ); @@ -334,7 +336,7 @@ void ContextVK::Setup(Settings settings) { /// Create the fence waiter. /// auto fence_waiter = - std::shared_ptr(new FenceWaiterVK(device.value.get())); + std::shared_ptr(new FenceWaiterVK(device.get())); if (!fence_waiter->IsValid()) { VALIDATION_LOG << "Could not create fence waiter."; return; @@ -343,7 +345,7 @@ void ContextVK::Setup(Settings settings) { //---------------------------------------------------------------------------- /// Fetch the queues. /// - QueuesVK queues(device.value.get(), // + QueuesVK queues(device.get(), // graphics_queue.value(), // compute_queue.value(), // transfer_queue.value() // @@ -363,7 +365,7 @@ void ContextVK::Setup(Settings settings) { instance_ = std::move(instance.value); debug_report_ = std::move(debug_report); physical_device_ = physical_device.value(); - device_ = std::move(device.value); + device_ = std::move(device); allocator_ = std::move(allocator); shader_library_ = std::move(shader_library); sampler_library_ = std::move(sampler_library); @@ -378,7 +380,7 @@ void ContextVK::Setup(Settings settings) { /// Label all the relevant objects. This happens after setup so that the debug /// messengers have had a chance to be setup. /// - SetDebugName(device_.get(), device_.get(), "ImpellerDevice"); + SetDebugName(GetDevice(), device_.get(), "ImpellerDevice"); } // |Context| @@ -421,8 +423,8 @@ vk::Instance ContextVK::GetInstance() const { return *instance_; } -vk::Device ContextVK::GetDevice() const { - return *device_; +const vk::Device& ContextVK::GetDevice() const { + return device_.get(); } std::unique_ptr ContextVK::AcquireNextSurface() { @@ -489,7 +491,7 @@ std::unique_ptr ContextVK::CreateGraphicsCommandEncoder() return nullptr; } auto encoder = std::unique_ptr(new CommandEncoderVK( - *device_, // + weak_from_this(), // queues_.graphics_queue, // tls_pool, // fence_waiter_ // diff --git a/impeller/renderer/backend/vulkan/context_vk.h b/impeller/renderer/backend/vulkan/context_vk.h index cc1376649bbbd..27d71ddeb5838 100644 --- a/impeller/renderer/backend/vulkan/context_vk.h +++ b/impeller/renderer/backend/vulkan/context_vk.h @@ -12,6 +12,7 @@ #include "flutter/fml/unique_fd.h" #include "impeller/base/backend_cast.h" #include "impeller/core/formats.h" +#include "impeller/renderer/backend/vulkan/device_holder.h" #include "impeller/renderer/backend/vulkan/pipeline_library_vk.h" #include "impeller/renderer/backend/vulkan/queue_vk.h" #include "impeller/renderer/backend/vulkan/sampler_library_vk.h" @@ -30,7 +31,10 @@ class CommandEncoderVK; class DebugReportVK; class FenceWaiterVK; -class ContextVK final : public Context, public BackendCast { +class ContextVK final : public Context, + public BackendCast, + public DeviceHolder, + public std::enable_shared_from_this { public: struct Settings { PFN_vkGetInstanceProcAddr proc_address_callback = nullptr; @@ -77,11 +81,11 @@ class ContextVK final : public Context, public BackendCast { template bool SetDebugName(T handle, std::string_view label) const { - return SetDebugName(*device_, handle, label); + return SetDebugName(GetDevice(), handle, label); } template - static bool SetDebugName(vk::Device device, + static bool SetDebugName(const vk::Device& device, T handle, std::string_view label) { if (!HasValidationLayers()) { @@ -106,7 +110,8 @@ class ContextVK final : public Context, public BackendCast { vk::Instance GetInstance() const; - vk::Device GetDevice() const; + // |DeviceHolder| + const vk::Device& GetDevice() const override; [[nodiscard]] bool SetWindowSurface(vk::UniqueSurfaceKHR surface); diff --git a/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc b/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc index ac53c63ea6499..7d2a6c4c5eccb 100644 --- a/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc +++ b/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc @@ -9,7 +9,11 @@ namespace impeller { -DescriptorPoolVK::DescriptorPoolVK(vk::Device device) : device_(device) {} +DescriptorPoolVK::DescriptorPoolVK( + std::weak_ptr device_holder) + : device_holder_(device_holder) { + FML_DCHECK(device_holder.lock()); +} DescriptorPoolVK::~DescriptorPoolVK() = default; @@ -44,7 +48,12 @@ std::optional DescriptorPoolVK::AllocateDescriptorSet( vk::DescriptorSetAllocateInfo set_info; set_info.setDescriptorPool(pool.value()); set_info.setSetLayouts(layout); - auto [result, sets] = device_.allocateDescriptorSets(set_info); + std::shared_ptr strong_device = device_holder_.lock(); + if (!strong_device) { + return std::nullopt; + } + auto [result, sets] = + strong_device->GetDevice().allocateDescriptorSets(set_info); if (result == vk::Result::eErrorOutOfPoolMemory) { return GrowPool() ? AllocateDescriptorSet(layout) : std::nullopt; } @@ -65,7 +74,11 @@ std::optional DescriptorPoolVK::GetDescriptorPool() { bool DescriptorPoolVK::GrowPool() { const auto new_pool_size = Allocation::NextPowerOfTwoSize(pool_size_ + 1u); - auto new_pool = CreatePool(device_, new_pool_size); + std::shared_ptr strong_device = device_holder_.lock(); + if (!strong_device) { + return false; + } + auto new_pool = CreatePool(strong_device->GetDevice(), new_pool_size); if (!new_pool) { return false; } diff --git a/impeller/renderer/backend/vulkan/descriptor_pool_vk.h b/impeller/renderer/backend/vulkan/descriptor_pool_vk.h index 4af9c0bc8b13a..5fb05d5827cb9 100644 --- a/impeller/renderer/backend/vulkan/descriptor_pool_vk.h +++ b/impeller/renderer/backend/vulkan/descriptor_pool_vk.h @@ -8,6 +8,7 @@ #include #include "flutter/fml/macros.h" +#include "impeller/renderer/backend/vulkan/device_holder.h" #include "impeller/renderer/backend/vulkan/vk.h" namespace impeller { @@ -26,7 +27,7 @@ namespace impeller { /// class DescriptorPoolVK { public: - explicit DescriptorPoolVK(vk::Device device); + explicit DescriptorPoolVK(std::weak_ptr device_holder); ~DescriptorPoolVK(); @@ -34,7 +35,7 @@ class DescriptorPoolVK { const vk::DescriptorSetLayout& layout); private: - const vk::Device device_; + std::weak_ptr device_holder_; uint32_t pool_size_ = 31u; std::queue pools_; diff --git a/impeller/renderer/backend/vulkan/device_holder.h b/impeller/renderer/backend/vulkan/device_holder.h new file mode 100644 index 0000000000000..cb9fdee248584 --- /dev/null +++ b/impeller/renderer/backend/vulkan/device_holder.h @@ -0,0 +1,17 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include "impeller/renderer/backend/vulkan/vk.h" + +namespace impeller { + +class DeviceHolder { + public: + virtual ~DeviceHolder() = default; + virtual const vk::Device& GetDevice() const = 0; +}; + +} // namespace impeller diff --git a/impeller/renderer/backend/vulkan/pipeline_cache_vk.cc b/impeller/renderer/backend/vulkan/pipeline_cache_vk.cc index 310c2fbb763ec..6d07881131454 100644 --- a/impeller/renderer/backend/vulkan/pipeline_cache_vk.cc +++ b/impeller/renderer/backend/vulkan/pipeline_cache_vk.cc @@ -53,12 +53,13 @@ static std::unique_ptr OpenCacheFile( } PipelineCacheVK::PipelineCacheVK(std::shared_ptr caps, - vk::Device device, + std::weak_ptr device_holder, + const vk::Device& device, fml::UniqueFD cache_directory) : caps_(std::move(caps)), - device_(device), + device_holder_(device_holder), cache_directory_(std::move(cache_directory)) { - if (!caps_ || !device_) { + if (!caps_ || !device) { return; } @@ -80,7 +81,7 @@ PipelineCacheVK::PipelineCacheVK(std::shared_ptr caps, cache_info.pInitialData = existing_cache_data->GetMapping(); } - auto [result, existing_cache] = device_.createPipelineCacheUnique(cache_info); + auto [result, existing_cache] = device.createPipelineCacheUnique(cache_info); if (result == vk::Result::eSuccess) { cache_ = std::move(existing_cache); @@ -92,7 +93,7 @@ PipelineCacheVK::PipelineCacheVK(std::shared_ptr caps, << vk::to_string(result) << ". Starting with a fresh cache."; cache_info.pInitialData = nullptr; cache_info.initialDataSize = 0u; - auto [result2, new_cache] = device_.createPipelineCacheUnique(cache_info); + auto [result2, new_cache] = device.createPipelineCacheUnique(cache_info); if (result2 == vk::Result::eSuccess) { cache_ = std::move(new_cache); } else { @@ -112,8 +113,14 @@ bool PipelineCacheVK::IsValid() const { vk::UniquePipeline PipelineCacheVK::CreatePipeline( const vk::GraphicsPipelineCreateInfo& info) { + std::shared_ptr strong_device = device_holder_.lock(); + if (!strong_device) { + return {}; + } + Lock lock(cache_mutex_); - auto [result, pipeline] = device_.createGraphicsPipelineUnique(*cache_, info); + auto [result, pipeline] = + strong_device->GetDevice().createGraphicsPipelineUnique(*cache_, info); if (result != vk::Result::eSuccess) { VALIDATION_LOG << "Could not create graphics pipeline: " << vk::to_string(result); @@ -122,11 +129,17 @@ vk::UniquePipeline PipelineCacheVK::CreatePipeline( } std::shared_ptr PipelineCacheVK::CopyPipelineCacheData() const { + std::shared_ptr strong_device = device_holder_.lock(); + if (!strong_device) { + return nullptr; + } + if (!IsValid()) { return nullptr; } Lock lock(cache_mutex_); - auto [result, data] = device_.getPipelineCacheData(*cache_); + auto [result, data] = + strong_device->GetDevice().getPipelineCacheData(*cache_); if (result != vk::Result::eSuccess) { VALIDATION_LOG << "Could not get pipeline cache data to persist."; return nullptr; diff --git a/impeller/renderer/backend/vulkan/pipeline_cache_vk.h b/impeller/renderer/backend/vulkan/pipeline_cache_vk.h index b6713ebb6cc10..bb90a32cfede4 100644 --- a/impeller/renderer/backend/vulkan/pipeline_cache_vk.h +++ b/impeller/renderer/backend/vulkan/pipeline_cache_vk.h @@ -8,14 +8,20 @@ #include "flutter/fml/macros.h" #include "impeller/base/thread.h" #include "impeller/renderer/backend/vulkan/capabilities_vk.h" +#include "impeller/renderer/backend/vulkan/device_holder.h" #include "impeller/renderer/backend/vulkan/vk.h" namespace impeller { class PipelineCacheVK { public: + // The [device] is passed in directly so that it can be used in the + // constructor directly. The [device_holder] isn't guaranteed to be valid + // at the time of executing `PipelineCacheVK` because of how `ContextVK` does + // initialization. explicit PipelineCacheVK(std::shared_ptr caps, - vk::Device device, + std::weak_ptr device_holder, + const vk::Device& device, fml::UniqueFD cache_directory); ~PipelineCacheVK(); @@ -28,7 +34,7 @@ class PipelineCacheVK { private: const std::shared_ptr caps_; - const vk::Device device_; + std::weak_ptr device_holder_; const fml::UniqueFD cache_directory_; mutable Mutex cache_mutex_; vk::UniquePipelineCache cache_ IPLR_GUARDED_BY(cache_mutex_); diff --git a/impeller/renderer/backend/vulkan/pipeline_library_vk.cc b/impeller/renderer/backend/vulkan/pipeline_library_vk.cc index 8717e35a02b34..22843ee4dc251 100644 --- a/impeller/renderer/backend/vulkan/pipeline_library_vk.cc +++ b/impeller/renderer/backend/vulkan/pipeline_library_vk.cc @@ -19,12 +19,14 @@ namespace impeller { PipelineLibraryVK::PipelineLibraryVK( + const std::weak_ptr& device_holder, const vk::Device& device, std::shared_ptr caps, fml::UniqueFD cache_directory, std::shared_ptr worker_task_runner) - : device_(device), + : device_holder_(device_holder), pso_cache_(std::make_shared(std::move(caps), + device_holder, device, std::move(cache_directory))), worker_task_runner_(std::move(worker_task_runner)) { @@ -225,7 +227,12 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( blend_state.setAttachments(attachment_blend_state); pipeline_info.setPColorBlendState(&blend_state); - auto render_pass = CreateRenderPass(device_, desc); + std::shared_ptr strong_device = device_holder_.lock(); + if (!strong_device) { + return nullptr; + } + + auto render_pass = CreateRenderPass(strong_device->GetDevice(), desc); if (render_pass) { pipeline_info.setBasePipelineHandle(VK_NULL_HANDLE); pipeline_info.setSubpass(0); @@ -279,13 +286,14 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( descs_layout_info.setBindings(desc_bindings); auto [descs_result, descs_layout] = - device_.createDescriptorSetLayoutUnique(descs_layout_info); + strong_device->GetDevice().createDescriptorSetLayoutUnique( + descs_layout_info); if (descs_result != vk::Result::eSuccess) { VALIDATION_LOG << "unable to create uniform descriptors"; return nullptr; } - ContextVK::SetDebugName(device_, descs_layout.get(), + ContextVK::SetDebugName(strong_device->GetDevice(), descs_layout.get(), "Descriptor Set Layout " + desc.GetLabel()); //---------------------------------------------------------------------------- @@ -293,8 +301,8 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( /// vk::PipelineLayoutCreateInfo pipeline_layout_info; pipeline_layout_info.setSetLayouts(descs_layout.get()); - auto pipeline_layout = - device_.createPipelineLayoutUnique(pipeline_layout_info); + auto pipeline_layout = strong_device->GetDevice().createPipelineLayoutUnique( + pipeline_layout_info); if (pipeline_layout.result != vk::Result::eSuccess) { VALIDATION_LOG << "Could not create pipeline layout for pipeline " << desc.GetLabel() << ": " @@ -321,9 +329,10 @@ std::unique_ptr PipelineLibraryVK::CreatePipeline( return nullptr; } - ContextVK::SetDebugName(device_, *pipeline_layout.value, + ContextVK::SetDebugName(strong_device->GetDevice(), *pipeline_layout.value, "Pipeline Layout " + desc.GetLabel()); - ContextVK::SetDebugName(device_, *pipeline, "Pipeline " + desc.GetLabel()); + ContextVK::SetDebugName(strong_device->GetDevice(), *pipeline, + "Pipeline " + desc.GetLabel()); return std::make_unique(weak_from_this(), // desc, // diff --git a/impeller/renderer/backend/vulkan/pipeline_library_vk.h b/impeller/renderer/backend/vulkan/pipeline_library_vk.h index 3e0c84ea4b70c..44b87e07d9a62 100644 --- a/impeller/renderer/backend/vulkan/pipeline_library_vk.h +++ b/impeller/renderer/backend/vulkan/pipeline_library_vk.h @@ -34,7 +34,7 @@ class PipelineLibraryVK final private: friend ContextVK; - vk::Device device_; + std::weak_ptr device_holder_; std::shared_ptr pso_cache_; std::shared_ptr worker_task_runner_; Mutex pipelines_mutex_; @@ -43,6 +43,7 @@ class PipelineLibraryVK final bool is_valid_ = false; PipelineLibraryVK( + const std::weak_ptr& device_holder, const vk::Device& device, std::shared_ptr caps, fml::UniqueFD cache_directory, diff --git a/impeller/renderer/backend/vulkan/swapchain_image_vk.cc b/impeller/renderer/backend/vulkan/swapchain_image_vk.cc index c87797df753ab..392c76b645a9b 100644 --- a/impeller/renderer/backend/vulkan/swapchain_image_vk.cc +++ b/impeller/renderer/backend/vulkan/swapchain_image_vk.cc @@ -7,7 +7,7 @@ namespace impeller { SwapchainImageVK::SwapchainImageVK(TextureDescriptor desc, - vk::Device device, + const vk::Device& device, vk::Image image) : TextureSourceVK(desc), image_(image) { vk::ImageViewCreateInfo view_info; diff --git a/impeller/renderer/backend/vulkan/swapchain_image_vk.h b/impeller/renderer/backend/vulkan/swapchain_image_vk.h index db905e834948c..6cf1943b8729e 100644 --- a/impeller/renderer/backend/vulkan/swapchain_image_vk.h +++ b/impeller/renderer/backend/vulkan/swapchain_image_vk.h @@ -14,7 +14,9 @@ namespace impeller { class SwapchainImageVK final : public TextureSourceVK { public: - SwapchainImageVK(TextureDescriptor desc, vk::Device device, vk::Image image); + SwapchainImageVK(TextureDescriptor desc, + const vk::Device& device, + vk::Image image); // |TextureSourceVK| ~SwapchainImageVK() override; diff --git a/impeller/renderer/context.h b/impeller/renderer/context.h index f270b0033eeb3..36bf48c6ed16f 100644 --- a/impeller/renderer/context.h +++ b/impeller/renderer/context.h @@ -19,7 +19,7 @@ class CommandBuffer; class PipelineLibrary; class Allocator; -class Context : public std::enable_shared_from_this { +class Context { public: virtual ~Context();