From 99a80374401a28b6f4025aef452c3175a3d46042 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 19 Oct 2021 14:00:20 -0700 Subject: [PATCH 01/60] Rebase atop https://github.com/flutter/engine/pull/29520 Previous commit: https://github.com/flutter/engine/pull/29391/commits/cdbb428b3d992473a315eb0c41d00652da82232c Add test context for loading swiftshader so update Remove unused things Prereqs to GPUSurfaceVulkan rewrite Comment typos --- shell/gpu/gpu_surface_metal_delegate.h | 4 +- shell/gpu/gpu_surface_vulkan.cc | 36 ++----- shell/gpu/gpu_surface_vulkan.h | 31 +++--- shell/gpu/gpu_surface_vulkan_delegate.h | 30 +++++- shell/platform/embedder/BUILD.gn | 16 +++- shell/platform/embedder/embedder.cc | 52 ++++++++++ shell/platform/embedder/embedder.h | 94 ++++++++++++++++++- .../embedder/platform_view_embedder.cc | 13 +++ .../embedder/platform_view_embedder.h | 14 +++ .../embedder/tests/embedder_assertions.h | 19 ++++ .../embedder/tests/embedder_config_builder.cc | 39 ++++++++ .../embedder/tests/embedder_config_builder.h | 5 + .../platform/embedder/tests/embedder_test.cc | 6 ++ .../embedder/tests/embedder_test_context.h | 1 + .../tests/embedder_test_context_vulkan.cc | 72 ++++++++++++++ .../tests/embedder_test_context_vulkan.h | 48 ++++++++++ .../embedder/tests/embedder_unittests_gl.cc | 9 ++ vulkan/vulkan_device.cc | 39 +++++++- vulkan/vulkan_device.h | 12 ++- vulkan/vulkan_swapchain.cc | 2 +- vulkan/vulkan_window.cc | 15 +-- vulkan/vulkan_window.h | 6 +- 22 files changed, 497 insertions(+), 66 deletions(-) create mode 100644 shell/platform/embedder/tests/embedder_test_context_vulkan.cc create mode 100644 shell/platform/embedder/tests/embedder_test_context_vulkan.h diff --git a/shell/gpu/gpu_surface_metal_delegate.h b/shell/gpu/gpu_surface_metal_delegate.h index 56112042fbc1d..cb3900e392c1f 100644 --- a/shell/gpu/gpu_surface_metal_delegate.h +++ b/shell/gpu/gpu_surface_metal_delegate.h @@ -75,14 +75,14 @@ class GPUSurfaceMetalDelegate { //------------------------------------------------------------------------------ /// @brief Returns the handle to the MTLTexture to render to. This is only - /// called when the specefied render target type is `kMTLTexture`. + /// called when the specified render target type is `kMTLTexture`. /// virtual GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_info) const = 0; //------------------------------------------------------------------------------ /// @brief Presents the texture with `texture_id` to the "screen". /// `texture_id` corresponds to a texture that has been obtained by an earlier - /// call to `GetMTLTexture`. This is only called when the specefied render + /// call to `GetMTLTexture`. This is only called when the specified render /// target type is `kMTLTexture`. /// /// @see |GPUSurfaceMetalDelegate::GetMTLTexture| diff --git a/shell/gpu/gpu_surface_vulkan.cc b/shell/gpu/gpu_surface_vulkan.cc index 570783bffa13d..b741ec806ea62 100644 --- a/shell/gpu/gpu_surface_vulkan.cc +++ b/shell/gpu/gpu_surface_vulkan.cc @@ -8,37 +8,19 @@ namespace flutter { -GPUSurfaceVulkan::GPUSurfaceVulkan( - GPUSurfaceVulkanDelegate* delegate, - std::unique_ptr native_surface, - bool render_to_surface) - : GPUSurfaceVulkan(/*context=*/nullptr, - delegate, - std::move(native_surface), - render_to_surface) {} - -GPUSurfaceVulkan::GPUSurfaceVulkan( - const sk_sp& context, - GPUSurfaceVulkanDelegate* delegate, - std::unique_ptr native_surface, - bool render_to_surface) - : window_(context, - delegate->vk(), - std::move(native_surface), - render_to_surface), - render_to_surface_(render_to_surface), - weak_factory_(this) {} +GPUSurfaceVulkan::GPUSurfaceVulkan(const sk_sp& skia_context, + GPUSurfaceVulkanDelegate* delegate) + : skia_context_(skia_context), delegate_(delegate), weak_factory_(this) {} GPUSurfaceVulkan::~GPUSurfaceVulkan() = default; bool GPUSurfaceVulkan::IsValid() { - return window_.IsValid(); + return image_ != nullptr; } std::unique_ptr GPUSurfaceVulkan::AcquireFrame( const SkISize& size) { - SurfaceFrame::FramebufferInfo framebuffer_info; - framebuffer_info.supports_readback = true; + VkImage image = delegate_->AcquireImage(size); // TODO(38466): Refactor GPU surface APIs take into account the fact that an // external view embedder may want to render to the root surface. @@ -50,7 +32,7 @@ std::unique_ptr GPUSurfaceVulkan::AcquireFrame( }); } - auto surface = window_.AcquireSurface(); + sk_sp surface = window_.AcquireSurface(); if (surface == nullptr) { return nullptr; @@ -65,12 +47,14 @@ std::unique_ptr GPUSurfaceVulkan::AcquireFrame( if (canvas == nullptr || !weak_this) { return false; } - return weak_this->window_.SwapBuffers(); + return weak_this->Present(); }; return std::make_unique( std::move(surface), std::move(framebuffer_info), std::move(callback)); } +bool GPUSurfaceVulkan::Present() {} + SkMatrix GPUSurfaceVulkan::GetRootTransformation() const { // This backend does not support delegating to the underlying platform to // query for root surface transformations. Just return identity. @@ -80,7 +64,7 @@ SkMatrix GPUSurfaceVulkan::GetRootTransformation() const { } GrDirectContext* GPUSurfaceVulkan::GetContext() { - return window_.GetSkiaGrContext(); + return skia_context_; } } // namespace flutter diff --git a/shell/gpu/gpu_surface_vulkan.h b/shell/gpu/gpu_surface_vulkan.h index 50c420e38790b..67997877f96b7 100644 --- a/shell/gpu/gpu_surface_vulkan.h +++ b/shell/gpu/gpu_surface_vulkan.h @@ -11,30 +11,26 @@ #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" +#include "flutter/vulkan/vulkan_backbuffer.h" #include "flutter/vulkan/vulkan_native_surface.h" #include "flutter/vulkan/vulkan_window.h" #include "include/core/SkRefCnt.h" namespace flutter { + +//------------------------------------------------------------------------------ +/// @brief A GPU surface backed by VkImages provided by a +/// GPUSurfaceVulkanDelegate. +/// class GPUSurfaceVulkan : public Surface { public: - //------------------------------------------------------------------------------ - /// @brief Create a GPUSurfaceVulkan which implicitly creates its own - /// GrDirectContext for Skia. - /// - GPUSurfaceVulkan(GPUSurfaceVulkanDelegate* delegate, - std::unique_ptr native_surface, - bool render_to_surface); - //------------------------------------------------------------------------------ /// @brief Create a GPUSurfaceVulkan while letting it reuse an existing /// GrDirectContext. /// GPUSurfaceVulkan(const sk_sp& context, - GPUSurfaceVulkanDelegate* delegate, - std::unique_ptr native_surface, - bool render_to_surface); + GPUSurfaceVulkanDelegate* delegate); ~GPUSurfaceVulkan() override; @@ -44,6 +40,11 @@ class GPUSurfaceVulkan : public Surface { // |Surface| std::unique_ptr AcquireFrame(const SkISize& size) override; + /// @brief Called when a frame is done rendering. It blocks on the render + /// fence and then calls `GPUSurfaceVulkanDelegate::PresentImage` with + /// the populated image. + bool Present(); + // |Surface| SkMatrix GetRootTransformation() const override; @@ -51,8 +52,12 @@ class GPUSurfaceVulkan : public Surface { GrDirectContext* GetContext() override; private: - vulkan::VulkanWindow window_; - const bool render_to_surface_; + sk_sp skia_context_; + GPUSurfaceVulkanDelegate* delegate_; + + std::vector> backbuffers_; + std::vector> surfaces_; + size_t current_backbuffer_index_; fml::WeakPtrFactory weak_factory_; FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceVulkan); diff --git a/shell/gpu/gpu_surface_vulkan_delegate.h b/shell/gpu/gpu_surface_vulkan_delegate.h index 9b1a495959562..e138804835255 100644 --- a/shell/gpu/gpu_surface_vulkan_delegate.h +++ b/shell/gpu/gpu_surface_vulkan_delegate.h @@ -6,16 +6,42 @@ #define FLUTTER_SHELL_GPU_GPU_SURFACE_VULKAN_DELEGATE_H_ #include "flutter/fml/memory/ref_ptr.h" +#include "flutter/vulkan/vulkan_device.h" +#include "flutter/vulkan/vulkan_image.h" #include "flutter/vulkan/vulkan_proc_table.h" +#include "third_party/skia/include/core/SkSize.h" namespace flutter { +//------------------------------------------------------------------------------ +/// @brief Interface implemented by all platform surfaces that can present +/// a Vulkan backing store to the "screen". The GPU surface +/// abstraction (which abstracts the client rendering API) uses this +/// delegation pattern to tell the platform surface (which abstracts +/// how backing stores fulfilled by the selected client rendering +/// API end up on the "screen" on a particular platform) when the +/// rasterizer needs to allocate and present the Vulkan backing +/// store. +/// +/// @see |EmbedderSurfaceVulkan|. +/// class GPUSurfaceVulkanDelegate { public: - ~GPUSurfaceVulkanDelegate(); + virtual ~GPUSurfaceVulkanDelegate(); - // Obtain a reference to the Vulkan implementation's proc table. + /// @brief Obtain a reference to the Vulkan implementation's proc table. + /// virtual fml::RefPtr vk() = 0; + + /// @brief Called by the engine to fetch a VkImage for writing the next + /// frame. + /// + virtual VkImage AcquireImage(const SkISize& size); + + /// @brief Called by the engine once a frame has been rendered to the image + /// and it's ready to be bound for further reading/writing. + /// + virtual bool PresentImage(VkImage image); }; } // namespace flutter diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 622432d2c11b1..a004aad176a4d 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -109,6 +109,13 @@ template("embedder_source_set") { deps += [ "//flutter/shell/platform/darwin/graphics" ] } + if (embedder_enable_gl) { + sources += [ + "embedder_surface_vulkan.cc", + "embedder_surface_vulkan.h", + ] + } + public_deps = [ ":embedder_headers" ] public_configs += [ @@ -234,7 +241,9 @@ if (enable_unittests) { "tests/embedder_unittests_gl.cc", ] - deps += [ "//flutter/testing:opengl" ] + deps += [ + "//flutter/testing:opengl", + ] } if (test_enable_metal) { @@ -250,6 +259,11 @@ if (enable_unittests) { } if (test_enable_vulkan) { + sources += [ + "tests/embedder_test_context_vulkan.cc", + "tests/embedder_test_context_vulkan.h", + ] + deps += [ "//flutter/testing:vulkan", "//flutter/vulkan", diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 838c4c496590a..d18c691bbb273 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -388,6 +388,41 @@ InferMetalPlatformViewCreationCallback( #endif } +static flutter::Shell::CreateCallback +InferVulkanPlatformViewCreationCallback( + const FlutterRendererConfig* config, + void* user_data, + flutter::PlatformViewEmbedder::PlatformDispatchTable + platform_dispatch_table, + std::unique_ptr + external_view_embedder) { + if (config->type != kVulkan) { + return nullptr; + } + +#ifdef SHELL_ENABLE_VULKAN + std::shared_ptr view_embedder = + std::move(external_view_embedder); + + std::unique_ptr embedder_surface = + std::make_unique(view_embedder); + + return fml::MakeCopyable( + [embedder_surface = std::move(embedder_surface), platform_dispatch_table, + external_view_embedder = view_embedder](flutter::Shell& shell) mutable { + return std::make_unique( + shell, // delegate + shell.GetTaskRunners(), // task runners + std::move(embedder_surface), // embedder surface + platform_dispatch_table, // platform dispatch table + std::move(external_view_embedder) // external view embedder + ); + }); +#else + return nullptr; +#endif +} + static flutter::Shell::CreateCallback InferSoftwarePlatformViewCreationCallback( const FlutterRendererConfig* config, @@ -450,6 +485,10 @@ InferPlatformViewCreationCallback( return InferMetalPlatformViewCreationCallback( config, user_data, platform_dispatch_table, std::move(external_view_embedder)); + case kVulkan: + return InferVulkanPlatformViewCreationCallback( + config, user_data, platform_dispatch_table, + std::move(external_view_embedder)); default: return nullptr; } @@ -628,6 +667,14 @@ static sk_sp MakeSkSurfaceFromBackingStore( #endif } +static sk_sp MakeSkSurfaceFromBackingStore( + GrDirectContext* context, + const FlutterBackingStoreConfig& config, + const FlutterVulkanBackingStore* vulkan) { + assert(false); // TODO(bdero) + return nullptr; +} + static std::unique_ptr CreateEmbedderRenderTarget(const FlutterCompositor* compositor, const FlutterBackingStoreConfig& config, @@ -689,6 +736,11 @@ CreateEmbedderRenderTarget(const FlutterCompositor* compositor, render_surface = MakeSkSurfaceFromBackingStore(context, config, &backing_store.metal); break; + + case kFlutterBackingStoreTypeVulkan: + render_surface = + MakeSkSurfaceFromBackingStore(context, config, &backing_store.vulkan); + break; }; if (!render_surface) { diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index e8b769ef4cbef..8370c99257455 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -76,6 +76,7 @@ typedef enum { /// iOS version >= 10.0 (device), 13.0 (simulator) /// macOS version >= 10.14 kMetal, + kVulkan, } FlutterRendererType; /// Additional accessibility features that may be enabled by the platform. @@ -494,7 +495,7 @@ typedef struct { size_t struct_size; /// Embedder provided unique identifier to the texture buffer. Given that the /// `texture` handle is passed to the engine to render to, the texture buffer - /// is itseld owned by the embedder. This `texture_id` is then also given to + /// is itself owned by the embedder. This `texture_id` is then also given to /// the embedder in the present callback. int64_t texture_id; /// Handle to the MTLTexture that is owned by the embedder. Engine will render @@ -541,6 +542,79 @@ typedef struct { FlutterMetalTextureFrameCallback external_texture_frame_callback; } FlutterMetalRendererConfig; +/// Alias for VkInstance. +typedef const uint64_t* FlutterVulkanInstanceHandle; + +/// Alias for VkPhysicalDevice. +typedef const uint64_t* FlutterVulkanPhysicalDeviceHandle; + +/// Alias for VkDevice. +typedef const uint64_t* FlutterVulkanDeviceHandle; + +/// Alias for VkQueue. +typedef const uint64_t* FlutterVulkanQueueHandle; + +/// Alias for VkImage. +typedef const uint64_t* FlutterVulkanImageHandle; + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterVulkanImage). + size_t struct_size; + /// Handle to the VkImage that is owned by the embedder. The engine will + /// bind this image for writing the frame. + FlutterVulkanImageHandle image; + /// A baton that is not interpreted by the engine in any way. It will be given + /// back to the embedder in the destruction callback below. Embedder resources + /// may be associated with this baton. + void* user_data; + /// The callback invoked by the engine when it no longer needs this backing + /// store. + VoidCallback destruction_callback; +} FlutterVulkanImage; + +/// Callback to fetch a Vulkan function pointer for a given instance. Normally, +/// this should return the results of vkGetInstanceProcAddr. +typedef void* (*FlutterVulkanInstanceProcAddressCallback)( + void* /* user data */, + FlutterVulkanInstanceHandle /* instance */, + const char* /* name */); + +/// Callback for when a VkImage is requested. +typedef FlutterVulkanImage (*FlutterVulkanImageCallback)( + void* /* user data */, + const FlutterFrameInfo* /* frame info */); + +/// Callback for when a VkImage has been written to and is ready for use by the +/// embedder. +typedef bool (*FlutterVulkanPresentCallback)( + void* /* user data */, + const FlutterVulkanImage* /* image */); +typedef uint64_t* (*Uint64Callback)(void* /* user data */); + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterVulkanRendererConfig). + size_t struct_size; + // VkInstance handle. + FlutterVulkanInstanceHandle instance; + // VkPhysicalDevice handle. + FlutterVulkanPhysicalDeviceHandle physical_device; + // VkDevice handle. + FlutterVulkanDeviceHandle device; + uint32_t queue_family_index; + // VkQueue handle. + FlutterVulkanQueueHandle queue; + FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback; + /// The callback invoked when the engine requests a VkImage from the embedder + /// for rendering the next frame. + FlutterVulkanImageCallback get_next_image_callback; + /// The callback invoked when a VkImage has been written to and is ready for + /// use by the embedder. Prior to calling this callback, the engine performs + /// a host sync, and so the VkImage can be used in a pipeline by the embedder + /// without any additional synchronization. + FlutterVulkanPresentCallback present_image_callback; + +} FlutterVulkanRendererConfig; + typedef struct { /// The size of this struct. Must be sizeof(FlutterSoftwareRendererConfig). size_t struct_size; @@ -557,6 +631,7 @@ typedef struct { FlutterOpenGLRendererConfig open_gl; FlutterSoftwareRendererConfig software; FlutterMetalRendererConfig metal; + FlutterVulkanRendererConfig vulkan; }; } FlutterRendererConfig; @@ -989,6 +1064,19 @@ typedef struct { }; } FlutterMetalBackingStore; +typedef struct { + /// The size of this struct. Must be sizeof(FlutterVulkanBackingStore). + size_t struct_size; + + /// The Vulkan image that the layer will be rendered to. This image must + /// already be available for the engine to bind for writing when it's given to + /// the engine via the backing store creation callback. The engine will + /// perform a host sync for all layers prior to calling the compositor present + /// callback, and so the written layer images can be freely bound by the + /// embedder without any additional synchronization. + FlutterVulkanImage image; +} FlutterVulkanBackingStore; + typedef enum { /// Indicates that the Flutter application requested that an opacity be /// applied to the platform view. @@ -1048,6 +1136,8 @@ typedef enum { kFlutterBackingStoreTypeSoftware, /// Specifies a Metal backing store. This is backed by a Metal texture. kFlutterBackingStoreTypeMetal, + /// Specifies a Vulkan backing store. This is backed by a Vulkan VkImage. + kFlutterBackingStoreTypeVulkan, } FlutterBackingStoreType; typedef struct { @@ -1069,6 +1159,8 @@ typedef struct { FlutterSoftwareBackingStore software; // The description of the Metal backing store. FlutterMetalBackingStore metal; + // The description of the Vulkan backing store. + FlutterVulkanBackingStore vulkan; }; } FlutterBackingStore; diff --git a/shell/platform/embedder/platform_view_embedder.cc b/shell/platform/embedder/platform_view_embedder.cc index 2a2752446f5e2..a24e13e2636d0 100644 --- a/shell/platform/embedder/platform_view_embedder.cc +++ b/shell/platform/embedder/platform_view_embedder.cc @@ -49,6 +49,19 @@ PlatformViewEmbedder::PlatformViewEmbedder( platform_dispatch_table_(platform_dispatch_table) {} #endif +#ifdef SHELL_ENABLE_VULKAN +PlatformViewEmbedder::PlatformViewEmbedder( + PlatformView::Delegate& delegate, + flutter::TaskRunners task_runners, + std::unique_ptr embedder_surface, + PlatformDispatchTable platform_dispatch_table, + std::shared_ptr external_view_embedder) + : PlatformView(delegate, std::move(task_runners)), + external_view_embedder_(external_view_embedder), + embedder_surface_(std::move(embedder_surface)), + platform_dispatch_table_(platform_dispatch_table) {} +#endif + PlatformViewEmbedder::~PlatformViewEmbedder() = default; void PlatformViewEmbedder::UpdateSemantics( diff --git a/shell/platform/embedder/platform_view_embedder.h b/shell/platform/embedder/platform_view_embedder.h index 22f4d2dee6ea0..61b4d6444c7bd 100644 --- a/shell/platform/embedder/platform_view_embedder.h +++ b/shell/platform/embedder/platform_view_embedder.h @@ -23,6 +23,10 @@ #include "flutter/shell/platform/embedder/embedder_surface_metal.h" #endif +#ifdef SHELL_ENABLE_METAL +#include "flutter/shell/platform/embedder/embedder_surface_vulkan.h" +#endif + namespace flutter { class PlatformViewEmbedder final : public PlatformView { @@ -79,6 +83,16 @@ class PlatformViewEmbedder final : public PlatformView { std::shared_ptr external_view_embedder); #endif +#ifdef SHELL_ENABLE_VULKAN + // Creates a platform view that sets up an Vulkan rasterizer. + PlatformViewEmbedder( + PlatformView::Delegate& delegate, + flutter::TaskRunners task_runners, + std::unique_ptr embedder_surface, + PlatformDispatchTable platform_dispatch_table, + std::shared_ptr external_view_embedder); +#endif + ~PlatformViewEmbedder() override; // |PlatformView| diff --git a/shell/platform/embedder/tests/embedder_assertions.h b/shell/platform/embedder/tests/embedder_assertions.h index 423c1239f34c7..7a4e519bf0d55 100644 --- a/shell/platform/embedder/tests/embedder_assertions.h +++ b/shell/platform/embedder/tests/embedder_assertions.h @@ -70,6 +70,11 @@ inline bool operator==(const FlutterMetalTexture& a, return a.texture_id == b.texture_id && a.texture == b.texture; } +inline bool operator==(const FlutterVulkanBackingStore& a, + const FlutterVulkanBackingStore& b) { + return a.handle == b.handle && a.image_ready == b.image_ready; +} + inline bool operator==(const FlutterMetalBackingStore& a, const FlutterMetalBackingStore& b) { return a.texture == b.texture; @@ -112,6 +117,8 @@ inline bool operator==(const FlutterBackingStore& a, return a.software == b.software; case kFlutterBackingStoreTypeMetal: return a.metal == b.metal; + case kFlutterBackingStoreTypeVulkan: + return a.vulkan == b.vulkan; } return false; @@ -230,6 +237,8 @@ inline std::string FlutterBackingStoreTypeToString( return "kFlutterBackingStoreTypeSoftware"; case kFlutterBackingStoreTypeMetal: return "kFlutterBackingStoreTypeMetal"; + case kFlutterBackingStoreTypeVulkan: + return "kFlutterBackingStoreTypeVulkan"; } return "Unknown"; } @@ -347,6 +356,12 @@ inline std::ostream& operator<<(std::ostream& out, return out << "(FlutterMetalBackingStore) Texture: " << item.texture; } +inline std::ostream& operator<<(std::ostream& out, + const FlutterVulkanBackingStore& item) { + return out << "(FlutterVulkanBackingStore) Handle: " << item.handle + << "Image Ready Semaphore: " << item.image_ready; +} + inline std::ostream& operator<<(std::ostream& out, const FlutterBackingStore& backing_store) { out << "(FlutterBackingStore) Struct size: " << backing_store.struct_size @@ -366,6 +381,10 @@ inline std::ostream& operator<<(std::ostream& out, case kFlutterBackingStoreTypeMetal: out << backing_store.metal; break; + + case kFlutterBackingStoreTypeVulkan: + out << backing_store.vulkan; + break; } return out; diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index d04188e0d3070..6d077e3e893a2 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -13,6 +13,10 @@ #include "flutter/shell/platform/embedder/tests/embedder_test_context_gl.h" #endif +//#ifdef SHELL_ENABLE_VULKAN +#include "flutter/shell/platform/embedder/tests/embedder_test_context_vulkan.h" +//#endif + #ifdef SHELL_ENABLE_METAL #include "flutter/shell/platform/embedder/tests/embedder_test_context_metal.h" #endif @@ -69,6 +73,41 @@ EmbedderConfigBuilder::EmbedderConfigBuilder( }; #endif + //#ifdef SHELL_ENABLE_VULKAN + vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); + vulkan_renderer_config_.get_proc_address_callback = + [](void* context, const char* name) -> void* { + return reinterpret_cast(context) + ->vk_->AcquireProc(name, nullptr); + }; + vulkan_renderer_config_.get_instance_proc_address_callback = + [](void* context, uintptr_t* instance, const char* name) -> void* { + return reinterpret_cast(context) + ->vk_->AcquireProc(name, instance); + }; + vulkan_renderer_config_.get_instance_handle_callback = + [](void* context) -> void* { + return reinterpret_cast(context) + ->application_->GetInstance(); + }; + vulkan_renderer_config_.get_physical_device_handle_callback = + [](void* context) -> void* { + return reinterpret_cast(context) + ->logical_device_->GetPhysicalDeviceHandle(); + }; + vulkan_renderer_config_.get_device_handle_callback = + [](void* context) -> void* { + return reinterpret_cast(context) + ->logical_device_->GetHandle(); + }; + vulkan_renderer_config_->acquire_next_image_callback = + [](void* context) -> void* { + // TODO(bdero): Return VkImage handles + return reinterpret_cast(context) + ->GetNextImage(); + }; + //#endif + #ifdef SHELL_ENABLE_METAL InitializeMetalRendererConfig(); #endif diff --git a/shell/platform/embedder/tests/embedder_config_builder.h b/shell/platform/embedder/tests/embedder_config_builder.h index ee1fb514bb611..be7f4282824ae 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.h +++ b/shell/platform/embedder/tests/embedder_config_builder.h @@ -49,6 +49,8 @@ class EmbedderConfigBuilder { void SetOpenGLRendererConfig(SkISize surface_size); + void SetVulkanRendererConfig(SkISize surface_size); + void SetMetalRendererConfig(SkISize surface_size); // Used to explicitly set an `open_gl.fbo_callback`. Using this method will @@ -117,6 +119,9 @@ class EmbedderConfigBuilder { #ifdef SHELL_ENABLE_GL FlutterOpenGLRendererConfig opengl_renderer_config_ = {}; #endif +//#ifdef SHELL_ENABLE_VULKAN + FlutterVulkanRendererConfig vulkan_renderer_config_ = {}; +//#endif #ifdef SHELL_ENABLE_METAL void InitializeMetalRendererConfig(); FlutterMetalRendererConfig metal_renderer_config_ = {}; diff --git a/shell/platform/embedder/tests/embedder_test.cc b/shell/platform/embedder/tests/embedder_test.cc index b816ab5d22307..0189a5c0457c9 100644 --- a/shell/platform/embedder/tests/embedder_test.cc +++ b/shell/platform/embedder/tests/embedder_test.cc @@ -4,6 +4,7 @@ #include "flutter/shell/platform/embedder/tests/embedder_test.h" #include "flutter/shell/platform/embedder/tests/embedder_test_context_software.h" +#include "flutter/shell/platform/embedder/tests/embedder_test_context_vulkan.h" #ifdef SHELL_ENABLE_GL #include "flutter/shell/platform/embedder/tests/embedder_test_context_gl.h" @@ -33,6 +34,11 @@ EmbedderTestContext& EmbedderTest::GetEmbedderContext( std::make_unique( GetFixturesDirectory()); break; + case EmbedderTestContextType::kVulkanContext: + embedder_contexts_[type] = + std::make_unique( + GetFixturesDirectory()); + break; #ifdef SHELL_ENABLE_GL case EmbedderTestContextType::kOpenGLContext: embedder_contexts_[type] = diff --git a/shell/platform/embedder/tests/embedder_test_context.h b/shell/platform/embedder/tests/embedder_test_context.h index 3f4f6d06b9c7d..74d2cd064b7b5 100644 --- a/shell/platform/embedder/tests/embedder_test_context.h +++ b/shell/platform/embedder/tests/embedder_test_context.h @@ -44,6 +44,7 @@ enum class EmbedderTestContextType { kSoftwareContext, kOpenGLContext, kMetalContext, + kVulkanContext, }; class EmbedderTestContext { diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc new file mode 100644 index 0000000000000..d8e42b63eec5a --- /dev/null +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -0,0 +1,72 @@ +// 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. + +#include "flutter/shell/platform/embedder/tests/embedder_test_context_vulkan.h" + +#include + +#include "embedder.h" +#include "flutter/fml/logging.h" +//#include +//"flutter/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h" + +#include "flutter/vulkan/vulkan_proc_table.h" + +#ifdef OS_MACOSX +#define VULKAN_SO_PATH "libvk_swiftshader.dylib" +#elif OS_WIN +#define VULKAN_SO_PATH "vk_swiftshader.dll" +#else +#define VULKAN_SO_PATH "libvk_swiftshader.so" +#endif + +namespace flutter { +namespace testing { + +EmbedderTestContextVulkan::EmbedderTestContextVulkan(std::string assets_path) + : EmbedderTestContext(assets_path) { + vk_ = fml::MakeRefCounted(VULKAN_SO_PATH); + FML_DCHECK(vk_->HasAcquiredMandatoryProcAddresses()); + + application_ = std::unique_ptr( + new vulkan::VulkanApplication(*vk_, "Flutter Unittests", {})); + FML_DCHECK(application_->IsValid()); + FML_DCHECK(vk_->AreInstanceProcsSetup()); + + logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); + FML_DCHECK(logical_device_ != nullptr); + FML_DCHECK(logical_device_->IsValid()); +} + +EmbedderTestContextVulkan::~EmbedderTestContextVulkan() {} + +void EmbedderTestContextVulkan::SetupSurface(SkISize surface_size) { + FML_CHECK(surface_size_.isEmpty()); + surface_size_ = surface_size; + + assert(false); // TODO(bdero) + // vulkan_surface_ = TestVulkanSurface::Create(*vulkan_context_, + // surface_size_); +} + +size_t EmbedderTestContextVulkan::GetSurfacePresentCount() const { + return present_count_; +} + +EmbedderTestContextType EmbedderTestContextVulkan::GetContextType() const { + return EmbedderTestContextType::kVulkanContext; +} + +void EmbedderTestContextVulkan::SetupCompositor() { + FML_CHECK(!compositor_) << "Already set up a compositor in this context."; + + assert(false); // TODO(bdero) + // FML_CHECK(vulkan_surface_) + // << "Set up the Vulkan surface before setting up a compositor."; + // compositor_ = std::make_unique( + // surface_size_, vulkan_surface_->GetGrContext()); +} + +} // namespace testing +} // namespace flutter diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.h b/shell/platform/embedder/tests/embedder_test_context_vulkan.h new file mode 100644 index 0000000000000..babdccdfcaa80 --- /dev/null +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.h @@ -0,0 +1,48 @@ +// 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. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONTEXT_VULKAN_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONTEXT_VULKAN_H_ + +#include "vulkan/vulkan_application.h" + +namespace flutter { +namespace testing { + +class EmbedderTestContextVulkan : public EmbedderTestContext { + public: + explicit EmbedderTestContextVulkan(std::string assets_path = ""); + + ~EmbedderTestContextVulkan() override; + + // |EmbedderTestContext| + EmbedderTestContextType GetContextType() const override; + + // |EmbedderTestContext| + size_t GetSurfacePresentCount() const override; + + // |EmbedderTestContext| + void SetupCompositor() override; + + private: + // This allows the builder to access the hooks. + friend class EmbedderConfigBuilder; + + fml::RefPtr vk_; + std::unique_ptr application_; + std::unique_ptr logical_device_; + + SkISize surface_size_ = SkISize::MakeEmpty(); + //std::unique_ptr vulkan_context_; + size_t present_count_ = 0; + + void SetupSurface(SkISize surface_size) override; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderTestContextVulkan); +}; + +} // namespace testing +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONTEXT_VULKAN_H_ diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index c8086191c8ba3..788c926ad78c0 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -7,6 +7,8 @@ #include #include +#include "vulkan/vulkan.h" + #include "embedder.h" #include "embedder_engine.h" #include "flutter/flow/raster_cache.h" @@ -15,6 +17,7 @@ #include "flutter/fml/mapping.h" #include "flutter/fml/message_loop.h" #include "flutter/fml/message_loop_task_queues.h" +#include "flutter/fml/native_library.h" #include "flutter/fml/paths.h" #include "flutter/fml/synchronization/count_down_latch.h" #include "flutter/fml/synchronization/waitable_event.h" @@ -31,6 +34,7 @@ #include "flutter/testing/test_gl_surface.h" #include "flutter/testing/test_vulkan_context.h" #include "flutter/testing/testing.h" +#include "flutter/vulkan/vulkan_proc_table.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/src/gpu/gl/GrGLDefines.h" #include "third_party/tonic/converter/dart_converter.h" @@ -50,6 +54,11 @@ TEST_F(EmbedderTest, CanInitializeTestVulkanContext) { ASSERT_TRUE(ctx.IsValid()); } +TEST_F(EmbedderTest, CanGetVulkanEmbedderContext) { + auto& context = GetEmbedderContext(EmbedderTestContextType::kVulkanContext); + EmbedderConfigBuilder builder(context); +} + TEST_F(EmbedderTest, CanCreateOpenGLRenderingEngine) { EmbedderConfigBuilder builder( GetEmbedderContext(EmbedderTestContextType::kOpenGLContext)); diff --git a/vulkan/vulkan_device.cc b/vulkan/vulkan_device.cc index e981329d2174b..3aacdb30ae488 100644 --- a/vulkan/vulkan_device.cc +++ b/vulkan/vulkan_device.cc @@ -35,8 +35,7 @@ VulkanDevice::VulkanDevice(VulkanProcTable& p_vk, : vk(p_vk), physical_device_(std::move(physical_device)), graphics_queue_index_(std::numeric_limits::max()), - valid_(false), - enable_validation_layers_(enable_validation_layers) { + valid_(false) { if (!physical_device_ || !vk.AreInstanceProcsSetup()) { return; } @@ -74,7 +73,7 @@ VulkanDevice::VulkanDevice(VulkanProcTable& p_vk, }; auto enabled_layers = - DeviceLayersToEnable(vk, physical_device_, enable_validation_layers_); + DeviceLayersToEnable(vk, physical_device_, enable_validation_layers); const char* layers[enabled_layers.size()]; @@ -122,6 +121,36 @@ VulkanDevice::VulkanDevice(VulkanProcTable& p_vk, queue_ = VulkanHandle(queue); + if (!InitializeCommandPool()) { + return; + } + + valid_ = true; +} + +VulkanDevice::VulkanDevice(VulkanProcTable& p_vk, + VulkanHandle physical_device, + VulkanHandle device, + uint32_t queue_family_index, + VulkanHandle queue) + : vk(p_vk), + physical_device_(std::move(physical_device)), + device_(std::move(device)), + graphics_queue_index_(queue_family_index), + queue_(std::move(queue)), + valid_(false) { + if (!physical_device_ || !vk.AreInstanceProcsSetup()) { + return; + } + + if (!InitializeCommandPool()) { + return; + } + + valid_ = true; +} + +bool VulkanDevice::InitializeCommandPool() { const VkCommandPoolCreateInfo command_pool_create_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .pNext = nullptr, @@ -134,7 +163,7 @@ VulkanDevice::VulkanDevice(VulkanProcTable& p_vk, nullptr, &command_pool)) != VK_SUCCESS) { FML_DLOG(INFO) << "Could not create the command pool."; - return; + return false; } command_pool_ = VulkanHandle{ @@ -142,7 +171,7 @@ VulkanDevice::VulkanDevice(VulkanProcTable& p_vk, vk.DestroyCommandPool(device_, pool, nullptr); }}; - valid_ = true; + return true; } VulkanDevice::~VulkanDevice() { diff --git a/vulkan/vulkan_device.h b/vulkan/vulkan_device.h index 73219ea098d94..22f848dd00e97 100644 --- a/vulkan/vulkan_device.h +++ b/vulkan/vulkan_device.h @@ -18,10 +18,20 @@ class VulkanSurface; class VulkanDevice { public: + /// @brief Create a new VkDevice with a resolved VkQueue suitable for + /// rendering with Skia. + /// VulkanDevice(VulkanProcTable& vk, VulkanHandle physical_device, bool enable_validation_layers); + /// @brief Wrap an existing VkDevice and VkQueue. + /// + VulkanDevice(VulkanProcTable& vk, + VulkanHandle physical_device, + VulkanHandle device, + uint32_t queue_family_index, + VulkanHandle queue); ~VulkanDevice(); bool IsValid() const; @@ -72,8 +82,8 @@ class VulkanDevice { VulkanHandle command_pool_; uint32_t graphics_queue_index_; bool valid_; - bool enable_validation_layers_; + bool InitializeCommandPool(); std::vector GetQueueFamilyProperties() const; FML_DISALLOW_COPY_AND_ASSIGN(VulkanDevice); diff --git a/vulkan/vulkan_swapchain.cc b/vulkan/vulkan_swapchain.cc index e33fd9742bcbc..7c3792d3fb571 100644 --- a/vulkan/vulkan_swapchain.cc +++ b/vulkan/vulkan_swapchain.cc @@ -350,7 +350,7 @@ VulkanSwapchain::AcquireResult VulkanSwapchain::AcquireSurface() { // --------------------------------------------------------------------------- // Step 2: - // Put semaphores in unsignaled state. + // Put fences in an unsignaled state. // --------------------------------------------------------------------------- if (!backbuffer->ResetFences()) { FML_DLOG(INFO) << "Could not reset fences."; diff --git a/vulkan/vulkan_window.cc b/vulkan/vulkan_window.cc index 1cee0820c615f..cf7730c7aa706 100644 --- a/vulkan/vulkan_window.cc +++ b/vulkan/vulkan_window.cc @@ -19,24 +19,21 @@ namespace vulkan { VulkanWindow::VulkanWindow(fml::RefPtr proc_table, - std::unique_ptr native_surface, - bool render_to_surface) + std::unique_ptr native_surface) : VulkanWindow(/*context/*/ nullptr, proc_table, - std::move(native_surface), - render_to_surface) {} + std::move(native_surface)) {} VulkanWindow::VulkanWindow(const sk_sp& context, fml::RefPtr proc_table, - std::unique_ptr native_surface, - bool render_to_surface) + std::unique_ptr native_surface) : valid_(false), vk(std::move(proc_table)), skia_gr_context_(context) { if (!vk || !vk->HasAcquiredMandatoryProcAddresses()) { FML_DLOG(INFO) << "Proc table has not acquired mandatory proc addresses."; return; } - if (native_surface == nullptr || !native_surface->IsValid()) { + if (native_surface && !native_surface->IsValid()) { FML_DLOG(INFO) << "Native surface is invalid."; return; } @@ -70,9 +67,7 @@ VulkanWindow::VulkanWindow(const sk_sp& context, return; } - // TODO(38466): Refactor GPU surface APIs take into account the fact that an - // external view embedder may want to render to the root surface. - if (!render_to_surface) { + if (!native_surface) { return; } diff --git a/vulkan/vulkan_window.h b/vulkan/vulkan_window.h index 685825024f7b8..bbaba38d47e1b 100644 --- a/vulkan/vulkan_window.h +++ b/vulkan/vulkan_window.h @@ -36,8 +36,7 @@ class VulkanWindow { /// GrDirectContext. /// VulkanWindow(fml::RefPtr proc_table, - std::unique_ptr native_surface, - bool render_to_surface); + std::unique_ptr native_surface); //------------------------------------------------------------------------------ /// @brief Construct a VulkanWindow. Let reuse an existing @@ -45,8 +44,7 @@ class VulkanWindow { /// VulkanWindow(const sk_sp& context, fml::RefPtr proc_table, - std::unique_ptr native_surface, - bool render_to_surface); + std::unique_ptr native_surface); ~VulkanWindow(); From 3586854597a54dc6cd156295ea22d383e81cd5db Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sat, 13 Nov 2021 16:12:51 -0800 Subject: [PATCH 02/60] Make sksurface from vkimage --- shell/gpu/gpu_surface_vulkan.cc | 5 +++++ shell/gpu/gpu_surface_vulkan.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/shell/gpu/gpu_surface_vulkan.cc b/shell/gpu/gpu_surface_vulkan.cc index b741ec806ea62..fc4d6ac17436d 100644 --- a/shell/gpu/gpu_surface_vulkan.cc +++ b/shell/gpu/gpu_surface_vulkan.cc @@ -67,4 +67,9 @@ GrDirectContext* GPUSurfaceVulkan::GetContext() { return skia_context_; } +sk_sp GPUSurfaceVulkan::AcquireSurfaceFromVulkanImage( + VkImage image) { + +} + } // namespace flutter diff --git a/shell/gpu/gpu_surface_vulkan.h b/shell/gpu/gpu_surface_vulkan.h index 67997877f96b7..9fd157ecf0111 100644 --- a/shell/gpu/gpu_surface_vulkan.h +++ b/shell/gpu/gpu_surface_vulkan.h @@ -60,6 +60,9 @@ class GPUSurfaceVulkan : public Surface { size_t current_backbuffer_index_; fml::WeakPtrFactory weak_factory_; + + sk_sp AcquireSurfaceFromVulkanImage(VkImage image); + FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceVulkan); }; From f5a46d80eee2d108b1dfd289b07dba2bb845e6ec Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 16 Nov 2021 03:09:13 -0800 Subject: [PATCH 03/60] Add EmbedderSurface for Vulkan, init skia contexts, correct API callbacks, init proctable, and init GPUSurfaceVulkan with callback delegate --- shell/gpu/gpu_surface_vulkan.cc | 18 +-- shell/gpu/gpu_surface_vulkan.h | 13 +- shell/gpu/gpu_surface_vulkan_delegate.h | 2 +- shell/platform/embedder/BUILD.gn | 7 - shell/platform/embedder/embedder.cc | 46 +++++- shell/platform/embedder/embedder.h | 14 +- .../embedder/embedder_surface_vulkan.cc | 134 ++++++++++++++++++ .../embedder/embedder_surface_vulkan.h | 78 ++++++++++ .../embedder/platform_view_embedder.h | 2 +- vulkan/vulkan_proc_table.cc | 29 ++-- vulkan/vulkan_proc_table.h | 15 +- 11 files changed, 314 insertions(+), 44 deletions(-) create mode 100644 shell/platform/embedder/embedder_surface_vulkan.cc create mode 100644 shell/platform/embedder/embedder_surface_vulkan.h diff --git a/shell/gpu/gpu_surface_vulkan.cc b/shell/gpu/gpu_surface_vulkan.cc index fc4d6ac17436d..3e3599feff967 100644 --- a/shell/gpu/gpu_surface_vulkan.cc +++ b/shell/gpu/gpu_surface_vulkan.cc @@ -8,14 +8,18 @@ namespace flutter { -GPUSurfaceVulkan::GPUSurfaceVulkan(const sk_sp& skia_context, - GPUSurfaceVulkanDelegate* delegate) - : skia_context_(skia_context), delegate_(delegate), weak_factory_(this) {} +GPUSurfaceVulkan::GPUSurfaceVulkan(GPUSurfaceVulkanDelegate* delegate, + const sk_sp& skia_context, + bool render_to_surface) + : delegate_(delegate), + skia_context_(skia_context), + render_to_surface_(render_to_surface), + weak_factory_(this) {} GPUSurfaceVulkan::~GPUSurfaceVulkan() = default; bool GPUSurfaceVulkan::IsValid() { - return image_ != nullptr; + return skia_context_ != nullptr; } std::unique_ptr GPUSurfaceVulkan::AcquireFrame( @@ -64,12 +68,10 @@ SkMatrix GPUSurfaceVulkan::GetRootTransformation() const { } GrDirectContext* GPUSurfaceVulkan::GetContext() { - return skia_context_; + return skia_context_.get(); } sk_sp GPUSurfaceVulkan::AcquireSurfaceFromVulkanImage( - VkImage image) { - -} + VkImage image) {} } // namespace flutter diff --git a/shell/gpu/gpu_surface_vulkan.h b/shell/gpu/gpu_surface_vulkan.h index 9fd157ecf0111..28277fcc5df01 100644 --- a/shell/gpu/gpu_surface_vulkan.h +++ b/shell/gpu/gpu_surface_vulkan.h @@ -18,7 +18,6 @@ namespace flutter { - //------------------------------------------------------------------------------ /// @brief A GPU surface backed by VkImages provided by a /// GPUSurfaceVulkanDelegate. @@ -29,8 +28,9 @@ class GPUSurfaceVulkan : public Surface { /// @brief Create a GPUSurfaceVulkan while letting it reuse an existing /// GrDirectContext. /// - GPUSurfaceVulkan(const sk_sp& context, - GPUSurfaceVulkanDelegate* delegate); + GPUSurfaceVulkan(GPUSurfaceVulkanDelegate* delegate, + const sk_sp& context, + bool render_to_surface); ~GPUSurfaceVulkan() override; @@ -52,11 +52,12 @@ class GPUSurfaceVulkan : public Surface { GrDirectContext* GetContext() override; private: - sk_sp skia_context_; GPUSurfaceVulkanDelegate* delegate_; + sk_sp skia_context_; + bool render_to_surface_; - std::vector> backbuffers_; - std::vector> surfaces_; + std::unique_ptr backbuffer_; + sk_sp surface_; size_t current_backbuffer_index_; fml::WeakPtrFactory weak_factory_; diff --git a/shell/gpu/gpu_surface_vulkan_delegate.h b/shell/gpu/gpu_surface_vulkan_delegate.h index e138804835255..8e620e20592cf 100644 --- a/shell/gpu/gpu_surface_vulkan_delegate.h +++ b/shell/gpu/gpu_surface_vulkan_delegate.h @@ -31,7 +31,7 @@ class GPUSurfaceVulkanDelegate { /// @brief Obtain a reference to the Vulkan implementation's proc table. /// - virtual fml::RefPtr vk() = 0; + virtual const vulkan::VulkanProcTable& vk() = 0; /// @brief Called by the engine to fetch a VkImage for writing the next /// frame. diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index a004aad176a4d..b97877b48daa3 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -109,13 +109,6 @@ template("embedder_source_set") { deps += [ "//flutter/shell/platform/darwin/graphics" ] } - if (embedder_enable_gl) { - sources += [ - "embedder_surface_vulkan.cc", - "embedder_surface_vulkan.h", - ] - } - public_deps = [ ":embedder_headers" ] public_configs += [ diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index d18c691bbb273..f100958151d1f 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "shell/gpu/gpu_surface_vulkan_delegate.h" +#include "shell/platform/embedder/embedder_surface_vulkan.h" #define FML_USED_ON_EMBEDDER #define RAPIDJSON_HAS_STDSTRING 1 @@ -401,11 +403,51 @@ InferVulkanPlatformViewCreationCallback( } #ifdef SHELL_ENABLE_VULKAN + std::function + vulkan_get_instance_proc_address = + [ptr = config->vulkan.get_instance_proc_address_callback, user_data]( + VkInstance instance, const char* proc_name) -> void* { + ptr(user_data, instance, proc_name); + }; + + auto vulkan_get_next_image = + [ptr = config->vulkan.get_next_image_callback, + user_data](const SkISize& frame_size) -> VkImage { + FlutterFrameInfo frame_info = { + .struct_size = sizeof(FlutterFrameInfo), + .size = {static_cast(frame_size.width()), + static_cast(frame_size.height())}, + }; + + FlutterVulkanImage vulkan_image = ptr(user_data, &frame_info); + return static_cast(vulkan_image.image); + }; + + auto vulkan_present_image_callback = + [ptr = config->vulkan.present_image_callback, + user_data](VkImage image) -> bool { + FlutterVulkanImage image_desc = { + .struct_size = sizeof(FlutterVulkanImage), + .image = image, + .user_data = user_data, + }; + return ptr(user_data, &image_desc); + }; + + flutter::EmbedderSurfaceVulkan::VulkanDispatchTable vulkan_dispatch_table = { + .get_instance_proc_address = vulkan_get_instance_proc_address, + .get_next_image = vulkan_get_next_image, + .present_image = vulkan_present_image_callback, + }; + std::shared_ptr view_embedder = std::move(external_view_embedder); std::unique_ptr embedder_surface = - std::make_unique(view_embedder); + std::make_unique( + config->vulkan.device, config->vulkan.physical_device, + config->vulkan.instance, config->vulkan.queue_family_index, + config->vulkan.queue, vulkan_dispatch_table, view_embedder); return fml::MakeCopyable( [embedder_surface = std::move(embedder_surface), platform_dispatch_table, @@ -671,7 +713,7 @@ static sk_sp MakeSkSurfaceFromBackingStore( GrDirectContext* context, const FlutterBackingStoreConfig& config, const FlutterVulkanBackingStore* vulkan) { - assert(false); // TODO(bdero) + assert(false); // TODO(bdero) return nullptr; } diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 8370c99257455..8e5a1075c7370 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -543,19 +543,19 @@ typedef struct { } FlutterMetalRendererConfig; /// Alias for VkInstance. -typedef const uint64_t* FlutterVulkanInstanceHandle; +typedef void* FlutterVulkanInstanceHandle; /// Alias for VkPhysicalDevice. -typedef const uint64_t* FlutterVulkanPhysicalDeviceHandle; +typedef void* FlutterVulkanPhysicalDeviceHandle; /// Alias for VkDevice. -typedef const uint64_t* FlutterVulkanDeviceHandle; +typedef void* FlutterVulkanDeviceHandle; /// Alias for VkQueue. -typedef const uint64_t* FlutterVulkanQueueHandle; +typedef void* FlutterVulkanQueueHandle; /// Alias for VkImage. -typedef const uint64_t* FlutterVulkanImageHandle; +typedef void* FlutterVulkanImageHandle; typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanImage). @@ -567,8 +567,8 @@ typedef struct { /// back to the embedder in the destruction callback below. Embedder resources /// may be associated with this baton. void* user_data; - /// The callback invoked by the engine when it no longer needs this backing - /// store. + /// Only called when releasing custom compositor backing stores. The callback + /// invoked by the engine when it no longer needs this backing store. VoidCallback destruction_callback; } FlutterVulkanImage; diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc new file mode 100644 index 0000000000000..c4a8ac0fdc121 --- /dev/null +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -0,0 +1,134 @@ +// 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. + +#include "flutter/shell/platform/embedder/embedder_surface_vulkan.h" + +#include "flutter/shell/common/shell_io_manager.h" +#include "include/gpu/GrDirectContext.h" +#include "include/gpu/vk/GrVkBackendContext.h" +#include "shell/gpu/gpu_surface_vulkan.h" +#include "shell/gpu/gpu_surface_vulkan_delegate.h" + +namespace flutter { + +EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( + VkInstance instance, + VkPhysicalDevice physical_device, + VkDevice device, + uint32_t queue_family_index, + VkQueue queue, + VulkanDispatchTable vulkan_dispatch_table, + std::shared_ptr external_view_embedder) + : vk_(vulkan_dispatch_table.get_instance_proc_address), + device_(vk_, physical_device, device, queue_family_index, queue), + vulkan_dispatch_table_(vulkan_dispatch_table), + external_view_embedder_(external_view_embedder) { + // Make sure all required members of the dispatch table are checked. + if (!vulkan_dispatch_table_.get_instance_proc_address || + !vulkan_dispatch_table_.get_next_image || + !vulkan_dispatch_table_.present_image) { + return; + } + + vk_.SetupInstanceProcAddresses(instance); + vk_.SetupDeviceProcAddresses(device); + if (!vk_.IsValid()) { + FML_LOG(ERROR) << "VulkanProcTable invalid."; + return; + } + + main_context_ = CreateGrContext(instance, ContextType::kRender); + // TODO(bdero): Add a second (optional) queue+family index to the Embedder API + // to allow embedders to specify a dedicated transfer queue for + // use by the resource context. Queue families with graphics + // capability can always be used for memory transferring, but it + // would be adventageous to use a dedicated transter queue here. + resource_context_ = CreateGrContext(instance, ContextType::kResource); + + valid_ = main_context_ && resource_context_; +} + +EmbedderSurfaceVulkan::~EmbedderSurfaceVulkan() = default; + +// |GPUSurfaceVulkanDelegate| +const vulkan::VulkanProcTable& EmbedderSurfaceVulkan::vk() { + return vk_; +} + +// |GPUSurfaceVulkanDelegate| +VkImage EmbedderSurfaceVulkan::AcquireImage(const SkISize& size) { + return vulkan_dispatch_table_.get_next_image(size); +} + +// |GPUSurfaceVulkanDelegate| +bool EmbedderSurfaceVulkan::PresentImage(VkImage image) { + return vulkan_dispatch_table_.present_image(image); +} + +// |EmbedderSurface| +bool EmbedderSurfaceVulkan::IsValid() const { + return valid_; +} + +// |EmbedderSurface| +std::unique_ptr EmbedderSurfaceVulkan::CreateGPUSurface() { + const bool render_to_surface = !external_view_embedder_; + return std::make_unique(this, main_context_, + render_to_surface); +} + +// |EmbedderSurface| +sk_sp EmbedderSurfaceVulkan::CreateResourceContext() const { + return resource_context_; +} + +sk_sp EmbedderSurfaceVulkan::CreateGrContext( + VkInstance instance, + ContextType context_type) const { + uint32_t skia_features = 0; + if (!device_.GetPhysicalDeviceFeaturesSkia(&skia_features)) { + FML_LOG(ERROR) << "Failed to get physical device features."; + + return nullptr; + } + + auto get_proc = vk_.CreateSkiaGetProc(); + if (get_proc == nullptr) { + FML_LOG(ERROR) << "Failed to create Vulkan getProc for Skia."; + return nullptr; + } + + GrVkBackendContext backend_context = { + .fInstance = instance, + .fPhysicalDevice = device_.GetPhysicalDeviceHandle(), + .fDevice = device_.GetHandle(), + .fQueue = device_.GetQueueHandle(), + .fGraphicsQueueIndex = device_.GetGraphicsQueueIndex(), + .fMinAPIVersion = VK_MAKE_VERSION(1, 0, 0), + .fMaxAPIVersion = VK_MAKE_VERSION(1, 0, 0), + .fFeatures = skia_features, + .fGetProc = get_proc, + .fOwnsInstanceAndDevice = false, + }; + // TODO(bdero): Activate MEMORY_REQUIREMENTS_2 if available because VMA (the + // allocator used by Skia) knows how to take advantage of these + // features. + /* + const char* device_extensions[] = { + VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, + }; + GrVkExtensions vk_extensions; + vk_extensions.init(backend_context.fGetProc, backend_context.fInstance, + backend_context.fPhysicalDevice, 0, nullptr, + countof(device_extensions), device_extensions); + backend_context.fVkExtensions = &vk_extensions; + */ + + GrContextOptions options = + MakeDefaultContextOptions(context_type, GrBackendApi::kVulkan); + options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; + return GrDirectContext::MakeVulkan(backend_context, options); +} + +} // namespace flutter diff --git a/shell/platform/embedder/embedder_surface_vulkan.h b/shell/platform/embedder/embedder_surface_vulkan.h new file mode 100644 index 0000000000000..fe13db8f7692d --- /dev/null +++ b/shell/platform/embedder/embedder_surface_vulkan.h @@ -0,0 +1,78 @@ +// 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. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SURFACE_VULKAN_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SURFACE_VULKAN_H_ + +#include "flutter/fml/macros.h" +#include "flutter/shell/gpu/gpu_surface_vulkan.h" +#include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_surface.h" +#include "shell/common/context_options.h" +#include "shell/gpu/gpu_surface_vulkan_delegate.h" +#include "shell/platform/embedder/embedder.h" +#include "vulkan/vulkan_proc_table.h" + +namespace flutter { + +class EmbedderSurfaceVulkan final : public EmbedderSurface, + public GPUSurfaceVulkanDelegate { + public: + struct VulkanDispatchTable { + std::function + get_instance_proc_address; // required + std::function + get_next_image; // required + std::function present_image; // required + }; + + EmbedderSurfaceVulkan( + VkInstance instance, + VkPhysicalDevice physical_device, + VkDevice device, + uint32_t queue_family_index, + VkQueue queue, + VulkanDispatchTable vulkan_dispatch_table, + std::shared_ptr external_view_embedder); + + ~EmbedderSurfaceVulkan() override; + + // |GPUSurfaceVulkanDelegate| + const vulkan::VulkanProcTable& vk() override; + + // |GPUSurfaceVulkanDelegate| + VkImage AcquireImage(const SkISize& size) override; + + // |GPUSurfaceVulkanDelegate| + bool PresentImage(VkImage image) override; + + private: + bool valid_ = false; + vulkan::VulkanProcTable vk_; + vulkan::VulkanDevice device_; + VulkanDispatchTable vulkan_dispatch_table_; + std::shared_ptr external_view_embedder_; + sk_sp main_context_; + sk_sp resource_context_; + + // |EmbedderSurface| + bool IsValid() const override; + + // |EmbedderSurface| + std::unique_ptr CreateGPUSurface() override; + + // |EmbedderSurface| + sk_sp CreateResourceContext() const override; + + sk_sp CreateGrContext(VkInstance instance, + ContextType context_type) const; + + void* GetInstanceProcAddress(VkInstance instance, const char* proc_name); + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceVulkan); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SURFACE_VULKAN_H_ diff --git a/shell/platform/embedder/platform_view_embedder.h b/shell/platform/embedder/platform_view_embedder.h index 61b4d6444c7bd..5c40ce1e16e79 100644 --- a/shell/platform/embedder/platform_view_embedder.h +++ b/shell/platform/embedder/platform_view_embedder.h @@ -23,7 +23,7 @@ #include "flutter/shell/platform/embedder/embedder_surface_metal.h" #endif -#ifdef SHELL_ENABLE_METAL +#ifdef SHELL_ENABLE_VULKAN #include "flutter/shell/platform/embedder/embedder_surface_vulkan.h" #endif diff --git a/vulkan/vulkan_proc_table.cc b/vulkan/vulkan_proc_table.cc index f5ba8f97bcb3c..535185e0a8f8a 100644 --- a/vulkan/vulkan_proc_table.cc +++ b/vulkan/vulkan_proc_table.cc @@ -16,10 +16,18 @@ namespace vulkan { VulkanProcTable::VulkanProcTable() : VulkanProcTable("libvulkan.so"){}; -VulkanProcTable::VulkanProcTable(const char* path) +VulkanProcTable::VulkanProcTable(const char* so_path) : handle_(nullptr), acquired_mandatory_proc_addresses_(false) { - acquired_mandatory_proc_addresses_ = - OpenLibraryHandle(path) && SetupLoaderProcAddresses(); + acquired_mandatory_proc_addresses_ = OpenLibraryHandle(so_path) && + SetupGetInstanceProcAddress() && + SetupLoaderProcAddresses(); +} + +VulkanProcTable::VulkanProcTable( + std::function get_instance_proc_addr) + : handle_(nullptr), acquired_mandatory_proc_addresses_(false) { + GetInstanceProcAddr = get_instance_proc_addr; + acquired_mandatory_proc_addresses_ = SetupLoaderProcAddresses(); } VulkanProcTable::~VulkanProcTable() { @@ -42,15 +50,15 @@ bool VulkanProcTable::AreDeviceProcsSetup() const { return device_; } -bool VulkanProcTable::SetupLoaderProcAddresses() { +bool VulkanProcTable::SetupGetInstanceProcAddress() { if (!handle_) { return true; } GetInstanceProcAddr = #if VULKAN_LINK_STATICALLY - GetInstanceProcAddr = &vkGetInstanceProcAddr; -#else // VULKAN_LINK_STATICALLY + &vkGetInstanceProcAddr; +#else // VULKAN_LINK_STATICALLY reinterpret_cast(const_cast( handle_->ResolveSymbol("vkGetInstanceProcAddr"))); #endif // VULKAN_LINK_STATICALLY @@ -60,6 +68,10 @@ bool VulkanProcTable::SetupLoaderProcAddresses() { return false; } + return true; +} + +bool VulkanProcTable::SetupLoaderProcAddresses() { VulkanHandle null_instance(VK_NULL_HANDLE, nullptr); ACQUIRE_PROC(CreateInstance, null_instance); @@ -154,7 +166,7 @@ bool VulkanProcTable::SetupDeviceProcAddresses( bool VulkanProcTable::OpenLibraryHandle(const char* path) { #if VULKAN_LINK_STATICALLY handle_ = fml::NativeLibrary::CreateForCurrentProcess(); -#else // VULKAN_LINK_STATICALLY +#else // VULKAN_LINK_STATICALLY handle_ = fml::NativeLibrary::Create(path); #endif // VULKAN_LINK_STATICALLY return !!handle_; @@ -173,7 +185,8 @@ PFN_vkVoidFunction VulkanProcTable::AcquireProc( } // A VK_NULL_HANDLE as the instance is an acceptable parameter. - return GetInstanceProcAddr(instance, proc_name); + return reinterpret_cast( + GetInstanceProcAddr(instance, proc_name)); } PFN_vkVoidFunction VulkanProcTable::AcquireProc( diff --git a/vulkan/vulkan_proc_table.h b/vulkan/vulkan_proc_table.h index a7f2a3d5f35b8..d4f623452da53 100644 --- a/vulkan/vulkan_proc_table.h +++ b/vulkan/vulkan_proc_table.h @@ -48,6 +48,13 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { T proc_; }; + VulkanProcTable(); + explicit VulkanProcTable(const char* so_path); + explicit VulkanProcTable( + std::function + get_instance_proc_addr); + ~VulkanProcTable(); + bool HasAcquiredMandatoryProcAddresses() const; bool IsValid() const; @@ -62,6 +69,9 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { GrVkGetProc CreateSkiaGetProc() const; + std::function + GetInstanceProcAddr = nullptr; + #define DEFINE_PROC(name) Proc name; DEFINE_PROC(AcquireNextImageKHR); @@ -98,7 +108,6 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { DEFINE_PROC(GetDeviceProcAddr); DEFINE_PROC(GetDeviceQueue); DEFINE_PROC(GetImageMemoryRequirements); - DEFINE_PROC(GetInstanceProcAddr); DEFINE_PROC(GetPhysicalDeviceFeatures); DEFINE_PROC(GetPhysicalDeviceQueueFamilyProperties); DEFINE_PROC(QueueSubmit); @@ -135,10 +144,8 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { VulkanHandle instance_; VulkanHandle device_; - VulkanProcTable(); - explicit VulkanProcTable(const char* path); - ~VulkanProcTable(); bool OpenLibraryHandle(const char* path); + bool SetupGetInstanceProcAddress(); bool SetupLoaderProcAddresses(); bool CloseLibraryHandle(); PFN_vkVoidFunction AcquireProc( From aa07175051f2ae224decf5828274def767b29464 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 17 Nov 2021 04:31:34 -0800 Subject: [PATCH 04/60] Make GPUSurfaceVulkan use delegate (EmbedderSurfaceVulkan) and create Vulkan-backed SkSurfaces used by EmbedderExternalViewEmbedder --- shell/gpu/gpu_surface_vulkan.cc | 85 ++++++++++++++++++++++------- shell/gpu/gpu_surface_vulkan.h | 12 +--- shell/platform/embedder/embedder.cc | 49 ++++++++++++++++- 3 files changed, 115 insertions(+), 31 deletions(-) diff --git a/shell/gpu/gpu_surface_vulkan.cc b/shell/gpu/gpu_surface_vulkan.cc index 3e3599feff967..722d0bb2bfcce 100644 --- a/shell/gpu/gpu_surface_vulkan.cc +++ b/shell/gpu/gpu_surface_vulkan.cc @@ -5,6 +5,8 @@ #include "flutter/shell/gpu/gpu_surface_vulkan.h" #include "flutter/fml/logging.h" +#include "fml/trace_event.h" +#include "include/core/SkSize.h" namespace flutter { @@ -23,42 +25,57 @@ bool GPUSurfaceVulkan::IsValid() { } std::unique_ptr GPUSurfaceVulkan::AcquireFrame( - const SkISize& size) { - VkImage image = delegate_->AcquireImage(size); + const SkISize& frame_size) { + if (!IsValid()) { + FML_LOG(ERROR) << "Vulkan surface was invalid."; + return nullptr; + } + + if (frame_size.isEmpty()) { + FML_LOG(ERROR) << "Vulkan surface was asked for an empty frame."; + return nullptr; + } - // TODO(38466): Refactor GPU surface APIs take into account the fact that an - // external view embedder may want to render to the root surface. if (!render_to_surface_) { return std::make_unique( - nullptr, std::move(framebuffer_info), + nullptr, SurfaceFrame::FramebufferInfo(), [](const SurfaceFrame& surface_frame, SkCanvas* canvas) { return true; }); } - sk_sp surface = window_.AcquireSurface(); + VkImage image = delegate_->AcquireImage(frame_size); + if (!image) { + FML_LOG(ERROR) << "Invalid VkImage given by the embedder."; + return nullptr; + } - if (surface == nullptr) { + sk_sp surface = CreateSurfaceFromVulkanImage(image, frame_size); + if (!surface) { + FML_LOG(ERROR) << "Could not create the SkSurface from the Vulkan image."; return nullptr; } - SurfaceFrame::SubmitCallback callback = - [weak_this = weak_factory_.GetWeakPtr()](const SurfaceFrame&, - SkCanvas* canvas) -> bool { - // Frames are only ever acquired on the raster thread. This is also the - // thread on which the weak pointer factory is collected (as this instance - // is owned by the rasterizer). So this use of weak pointers is safe. - if (canvas == nullptr || !weak_this) { + SurfaceFrame::SubmitCallback callback = [image = image, delegate = delegate_]( + const SurfaceFrame&, + SkCanvas* canvas) -> bool { + TRACE_EVENT0("flutter", "GPUSurfaceVulkan::PresentImage"); + if (canvas == nullptr) { + FML_DLOG(ERROR) << "Canvas not available."; return false; } - return weak_this->Present(); + + canvas->flush(); + + return delegate->PresentImage(image); }; + + SurfaceFrame::FramebufferInfo framebuffer_info{.supports_readback = true}; + return std::make_unique( std::move(surface), std::move(framebuffer_info), std::move(callback)); } -bool GPUSurfaceVulkan::Present() {} - SkMatrix GPUSurfaceVulkan::GetRootTransformation() const { // This backend does not support delegating to the underlying platform to // query for root surface transformations. Just return identity. @@ -71,7 +88,37 @@ GrDirectContext* GPUSurfaceVulkan::GetContext() { return skia_context_.get(); } -sk_sp GPUSurfaceVulkan::AcquireSurfaceFromVulkanImage( - VkImage image) {} +sk_sp GPUSurfaceVulkan::CreateSurfaceFromVulkanImage( + VkImage image, + const SkISize& size) { + GrVkImageInfo image_info = { + .fImage = image, + .fImageTiling = VK_IMAGE_TILING_OPTIMAL, + .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .fFormat = VK_FORMAT_R8G8B8A8_UNORM, + .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT, + .fSampleCount = 1, + .fLevelCount = 1, + }; + GrBackendTexture backend_texture(size.width(), // + size.height(), // + image_info // + ); + + SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); + + return SkSurface::MakeFromBackendTexture( + skia_context_.get(), // context + backend_texture, // back-end texture + kTopLeft_GrSurfaceOrigin, // surface origin + 1, // sample count + kRGBA_8888_SkColorType, // color type + SkColorSpace::MakeSRGB(), // color space + &surface_properties // surface properties + ); +} } // namespace flutter diff --git a/shell/gpu/gpu_surface_vulkan.h b/shell/gpu/gpu_surface_vulkan.h index 28277fcc5df01..3baf890a0158f 100644 --- a/shell/gpu/gpu_surface_vulkan.h +++ b/shell/gpu/gpu_surface_vulkan.h @@ -40,11 +40,6 @@ class GPUSurfaceVulkan : public Surface { // |Surface| std::unique_ptr AcquireFrame(const SkISize& size) override; - /// @brief Called when a frame is done rendering. It blocks on the render - /// fence and then calls `GPUSurfaceVulkanDelegate::PresentImage` with - /// the populated image. - bool Present(); - // |Surface| SkMatrix GetRootTransformation() const override; @@ -56,13 +51,10 @@ class GPUSurfaceVulkan : public Surface { sk_sp skia_context_; bool render_to_surface_; - std::unique_ptr backbuffer_; - sk_sp surface_; - size_t current_backbuffer_index_; - fml::WeakPtrFactory weak_factory_; - sk_sp AcquireSurfaceFromVulkanImage(VkImage image); + sk_sp CreateSurfaceFromVulkanImage(VkImage image, + const SkISize& size); FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceVulkan); }; diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index f100958151d1f..665192956880c 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -407,7 +407,7 @@ InferVulkanPlatformViewCreationCallback( vulkan_get_instance_proc_address = [ptr = config->vulkan.get_instance_proc_address_callback, user_data]( VkInstance instance, const char* proc_name) -> void* { - ptr(user_data, instance, proc_name); + return ptr(user_data, instance, proc_name); }; auto vulkan_get_next_image = @@ -713,8 +713,53 @@ static sk_sp MakeSkSurfaceFromBackingStore( GrDirectContext* context, const FlutterBackingStoreConfig& config, const FlutterVulkanBackingStore* vulkan) { - assert(false); // TODO(bdero) +#ifdef SHELL_ENABLE_VULKAN + if (!vulkan->image.image) { + FML_LOG(ERROR) << "Embedder supplied null Vulkan image."; + return nullptr; + } + + GrVkImageInfo image_info = { + .fImage = static_cast(vulkan->image.image), + .fImageTiling = VK_IMAGE_TILING_OPTIMAL, + .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .fFormat = VK_FORMAT_R8G8B8A8_UNORM, + .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT, + .fSampleCount = 1, + .fLevelCount = 1, + }; + GrBackendTexture backend_texture(config.size.width, // + config.size.height, // + image_info // + ); + + SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); + + auto surface = SkSurface::MakeFromBackendTexture( + context, // context + backend_texture, // back-end texture + kTopLeft_GrSurfaceOrigin, // surface origin + 1, // sample count + kRGBA_8888_SkColorType, // color type + SkColorSpace::MakeSRGB(), // color space + &surface_properties, // surface properties + static_cast( + vulkan->image.destruction_callback), // release proc + vulkan->image.user_data // release context + ); + + if (!surface) { + FML_LOG(ERROR) << "Could not wrap embedder supplied Vulkan render texture."; + return nullptr; + } + + return surface; +#else return nullptr; +#endif } static std::unique_ptr From e2280fda5bcc2288dd478df3c0c27ea4cc58cbb0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 17 Nov 2021 05:34:22 -0800 Subject: [PATCH 05/60] Build fixup --- shell/platform/embedder/embedder.cc | 11 +++-- .../embedder/tests/embedder_assertions.h | 17 +++++-- .../embedder/tests/embedder_config_builder.cc | 47 +++++++++---------- .../embedder/tests/embedder_unittests_gl.cc | 18 +++---- 4 files changed, 51 insertions(+), 42 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 665192956880c..e1c89a486e7d9 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "shell/gpu/gpu_surface_vulkan_delegate.h" -#include "shell/platform/embedder/embedder_surface_vulkan.h" #define FML_USED_ON_EMBEDDER #define RAPIDJSON_HAS_STDSTRING 1 @@ -445,9 +443,12 @@ InferVulkanPlatformViewCreationCallback( std::unique_ptr embedder_surface = std::make_unique( - config->vulkan.device, config->vulkan.physical_device, - config->vulkan.instance, config->vulkan.queue_family_index, - config->vulkan.queue, vulkan_dispatch_table, view_embedder); + static_cast(config->vulkan.instance), + static_cast(config->vulkan.physical_device), + static_cast(config->vulkan.device), + config->vulkan.queue_family_index, + static_cast(config->vulkan.queue), vulkan_dispatch_table, + view_embedder); return fml::MakeCopyable( [embedder_surface = std::move(embedder_surface), platform_dispatch_table, diff --git a/shell/platform/embedder/tests/embedder_assertions.h b/shell/platform/embedder/tests/embedder_assertions.h index 7a4e519bf0d55..7c4f877533c93 100644 --- a/shell/platform/embedder/tests/embedder_assertions.h +++ b/shell/platform/embedder/tests/embedder_assertions.h @@ -70,9 +70,14 @@ inline bool operator==(const FlutterMetalTexture& a, return a.texture_id == b.texture_id && a.texture == b.texture; } +inline bool operator==(const FlutterVulkanImage& a, + const FlutterVulkanImage& b) { + return a.image == b.image; +} + inline bool operator==(const FlutterVulkanBackingStore& a, const FlutterVulkanBackingStore& b) { - return a.handle == b.handle && a.image_ready == b.image_ready; + return a.image == b.image; } inline bool operator==(const FlutterMetalBackingStore& a, @@ -265,6 +270,13 @@ inline std::ostream& operator<<(std::ostream& out, << item.texture_id << std::dec << " Handle: 0x" << std::hex << item.texture; } + +inline std::ostream& operator<<(std::ostream& out, + const FlutterVulkanImage& item) { + return out << "(FlutterVulkanTexture) Image Handle: " << std::hex + << item.image; +} + inline std::string FlutterPlatformViewMutationTypeToString( FlutterPlatformViewMutationType type) { switch (type) { @@ -358,8 +370,7 @@ inline std::ostream& operator<<(std::ostream& out, inline std::ostream& operator<<(std::ostream& out, const FlutterVulkanBackingStore& item) { - return out << "(FlutterVulkanBackingStore) Handle: " << item.handle - << "Image Ready Semaphore: " << item.image_ready; + return out << "(FlutterVulkanBackingStore) Image: " << item.image; } inline std::ostream& operator<<(std::ostream& out, diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 6d077e3e893a2..574d5334c905f 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -73,40 +73,37 @@ EmbedderConfigBuilder::EmbedderConfigBuilder( }; #endif - //#ifdef SHELL_ENABLE_VULKAN + #ifdef SHELL_ENABLE_VULKAN vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); - vulkan_renderer_config_.get_proc_address_callback = - [](void* context, const char* name) -> void* { - return reinterpret_cast(context) - ->vk_->AcquireProc(name, nullptr); - }; + vulkan_renderer_config_.instance = + reinterpret_cast(context) + ->application_->GetInstance(); + vulkan_renderer_config_.physical_device = + reinterpret_cast(context) + ->application_->GetPhysicalDevice(); + vulkan_renderer_config_.device = + reinterpret_cast(context) + ->application_->GetDevice(); + vulkan_renderer_config_.queue_family_index = + reinterpret_cast(context) + ->application_->GetQueueFamilyIndex(); + vulkan_renderer_config_.queue = + reinterpret_cast(context) + ->application_->GetQueue(); vulkan_renderer_config_.get_instance_proc_address_callback = [](void* context, uintptr_t* instance, const char* name) -> void* { return reinterpret_cast(context) ->vk_->AcquireProc(name, instance); }; - vulkan_renderer_config_.get_instance_handle_callback = - [](void* context) -> void* { - return reinterpret_cast(context) - ->application_->GetInstance(); - }; - vulkan_renderer_config_.get_physical_device_handle_callback = - [](void* context) -> void* { - return reinterpret_cast(context) - ->logical_device_->GetPhysicalDeviceHandle(); - }; - vulkan_renderer_config_.get_device_handle_callback = - [](void* context) -> void* { - return reinterpret_cast(context) - ->logical_device_->GetHandle(); - }; - vulkan_renderer_config_->acquire_next_image_callback = + vulkan_renderer_config_->get_next_image_callback = [](void* context) -> void* { // TODO(bdero): Return VkImage handles - return reinterpret_cast(context) - ->GetNextImage(); + return reinterpret_cast(context)->GetNextImage(); + }; + vulkan_renderer_config_->present_image_callback = [](void* context) -> void* { + return reinterpret_cast(context)->PresentImage(); }; - //#endif + #endif #ifdef SHELL_ENABLE_METAL InitializeMetalRendererConfig(); diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 788c926ad78c0..2d3c52a99e93d 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -49,15 +49,15 @@ using EmbedderTest = testing::EmbedderTest; /// support lands in the embedder API, it'll be tested via a new /// EmbedderTestContext type/config. /// -TEST_F(EmbedderTest, CanInitializeTestVulkanContext) { - TestVulkanContext ctx; - ASSERT_TRUE(ctx.IsValid()); -} - -TEST_F(EmbedderTest, CanGetVulkanEmbedderContext) { - auto& context = GetEmbedderContext(EmbedderTestContextType::kVulkanContext); - EmbedderConfigBuilder builder(context); -} +//TEST_F(EmbedderTest, CanInitializeTestVulkanContext) { +// TestVulkanContext ctx; +// ASSERT_TRUE(ctx.IsValid()); +//} + +//TEST_F(EmbedderTest, CanGetVulkanEmbedderContext) { +// auto& context = GetEmbedderContext(EmbedderTestContextType::kVulkanContext); +// EmbedderConfigBuilder builder(context); +//} TEST_F(EmbedderTest, CanCreateOpenGLRenderingEngine) { EmbedderConfigBuilder builder( From 0572e7042dbf1d7309951511b38a9f32746ae903 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 17 Nov 2021 23:29:39 -0800 Subject: [PATCH 06/60] API change: Move backing store specific stuff out of FlutterVulkanImage --- shell/gpu/BUILD.gn | 3 +- shell/gpu/gpu_surface_vulkan_delegate.h | 4 +- shell/platform/embedder/BUILD.gn | 11 ++-- shell/platform/embedder/embedder.cc | 5 +- shell/platform/embedder/embedder.h | 16 +++--- .../embedder/tests/embedder_config_builder.cc | 54 +++++++++++-------- .../tests/embedder_test_context_vulkan.cc | 37 ++++++++++--- .../tests/embedder_test_context_vulkan.h | 5 ++ .../embedder/tests/embedder_unittests_gl.cc | 20 ++----- testing/BUILD.gn | 5 -- testing/test_vulkan_context.cc | 52 ------------------ testing/test_vulkan_context.h | 33 ------------ vulkan/vulkan_proc_table.cc | 6 ++- 13 files changed, 98 insertions(+), 153 deletions(-) delete mode 100644 testing/test_vulkan_context.cc delete mode 100644 testing/test_vulkan_context.h diff --git a/shell/gpu/BUILD.gn b/shell/gpu/BUILD.gn index 9687b94fbb2b2..4449f084bf23b 100644 --- a/shell/gpu/BUILD.gn +++ b/shell/gpu/BUILD.gn @@ -44,7 +44,8 @@ source_set("gpu_surface_vulkan") { "gpu_surface_vulkan_delegate.h", ] - deps = gpu_common_deps + [ "//flutter/vulkan" ] + deps = gpu_common_deps + public_deps = [ "//flutter/vulkan" ] } source_set("gpu_surface_metal") { diff --git a/shell/gpu/gpu_surface_vulkan_delegate.h b/shell/gpu/gpu_surface_vulkan_delegate.h index 8e620e20592cf..6e18204904cc5 100644 --- a/shell/gpu/gpu_surface_vulkan_delegate.h +++ b/shell/gpu/gpu_surface_vulkan_delegate.h @@ -36,12 +36,12 @@ class GPUSurfaceVulkanDelegate { /// @brief Called by the engine to fetch a VkImage for writing the next /// frame. /// - virtual VkImage AcquireImage(const SkISize& size); + virtual VkImage AcquireImage(const SkISize& size) = 0; /// @brief Called by the engine once a frame has been rendered to the image /// and it's ready to be bound for further reading/writing. /// - virtual bool PresentImage(VkImage image); + virtual bool PresentImage(VkImage image) = 0; }; } // namespace flutter diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index b97877b48daa3..28483d80965b0 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -109,6 +109,13 @@ template("embedder_source_set") { deps += [ "//flutter/shell/platform/darwin/graphics" ] } + if (embedder_enable_vulkan) { + sources += [ + "embedder_surface_vulkan.cc", + "embedder_surface_vulkan.h", + ] + } + public_deps = [ ":embedder_headers" ] public_configs += [ @@ -234,9 +241,7 @@ if (enable_unittests) { "tests/embedder_unittests_gl.cc", ] - deps += [ - "//flutter/testing:opengl", - ] + deps += [ "//flutter/testing:opengl" ] } if (test_enable_metal) { diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index e1c89a486e7d9..4f287f153e9f0 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -427,7 +427,6 @@ InferVulkanPlatformViewCreationCallback( FlutterVulkanImage image_desc = { .struct_size = sizeof(FlutterVulkanImage), .image = image, - .user_data = user_data, }; return ptr(user_data, &image_desc); }; @@ -748,8 +747,8 @@ static sk_sp MakeSkSurfaceFromBackingStore( SkColorSpace::MakeSRGB(), // color space &surface_properties, // surface properties static_cast( - vulkan->image.destruction_callback), // release proc - vulkan->image.user_data // release context + vulkan->destruction_callback), // release proc + vulkan->user_data // release context ); if (!surface) { diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 8e5a1075c7370..b401638d18568 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -563,13 +563,6 @@ typedef struct { /// Handle to the VkImage that is owned by the embedder. The engine will /// bind this image for writing the frame. FlutterVulkanImageHandle image; - /// A baton that is not interpreted by the engine in any way. It will be given - /// back to the embedder in the destruction callback below. Embedder resources - /// may be associated with this baton. - void* user_data; - /// Only called when releasing custom compositor backing stores. The callback - /// invoked by the engine when it no longer needs this backing store. - VoidCallback destruction_callback; } FlutterVulkanImage; /// Callback to fetch a Vulkan function pointer for a given instance. Normally, @@ -589,7 +582,6 @@ typedef FlutterVulkanImage (*FlutterVulkanImageCallback)( typedef bool (*FlutterVulkanPresentCallback)( void* /* user data */, const FlutterVulkanImage* /* image */); -typedef uint64_t* (*Uint64Callback)(void* /* user data */); typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanRendererConfig). @@ -1067,7 +1059,6 @@ typedef struct { typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanBackingStore). size_t struct_size; - /// The Vulkan image that the layer will be rendered to. This image must /// already be available for the engine to bind for writing when it's given to /// the engine via the backing store creation callback. The engine will @@ -1075,6 +1066,13 @@ typedef struct { /// callback, and so the written layer images can be freely bound by the /// embedder without any additional synchronization. FlutterVulkanImage image; + /// A baton that is not interpreted by the engine in any way. It will be given + /// back to the embedder in the destruction callback below. Embedder resources + /// may be associated with this baton. + void* user_data; + /// The callback invoked by the engine when it no longer needs this backing + /// store. + VoidCallback destruction_callback; } FlutterVulkanBackingStore; typedef enum { diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 574d5334c905f..fd63a16fc99a0 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -15,6 +15,7 @@ //#ifdef SHELL_ENABLE_VULKAN #include "flutter/shell/platform/embedder/tests/embedder_test_context_vulkan.h" +#include "flutter/vulkan/vulkan_device.h" //#endif #ifdef SHELL_ENABLE_METAL @@ -73,37 +74,48 @@ EmbedderConfigBuilder::EmbedderConfigBuilder( }; #endif - #ifdef SHELL_ENABLE_VULKAN +#ifdef SHELL_ENABLE_VULKAN vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); vulkan_renderer_config_.instance = - reinterpret_cast(context) - ->application_->GetInstance(); + static_cast(context) + .application_->GetInstance(); vulkan_renderer_config_.physical_device = - reinterpret_cast(context) - ->application_->GetPhysicalDevice(); + static_cast(context) + .logical_device_->GetPhysicalDeviceHandle(); vulkan_renderer_config_.device = - reinterpret_cast(context) - ->application_->GetDevice(); + static_cast(context) + .logical_device_->GetHandle(); vulkan_renderer_config_.queue_family_index = - reinterpret_cast(context) - ->application_->GetQueueFamilyIndex(); + static_cast(context) + .logical_device_->GetGraphicsQueueIndex(); vulkan_renderer_config_.queue = - reinterpret_cast(context) - ->application_->GetQueue(); + static_cast(context) + .logical_device_->GetQueueHandle(); vulkan_renderer_config_.get_instance_proc_address_callback = - [](void* context, uintptr_t* instance, const char* name) -> void* { - return reinterpret_cast(context) - ->vk_->AcquireProc(name, instance); + [](void* context, FlutterVulkanInstanceHandle instance, + const char* name) -> void* { + return reinterpret_cast(context) + ->vk_->GetInstanceProcAddr(reinterpret_cast(instance), + name); }; - vulkan_renderer_config_->get_next_image_callback = - [](void* context) -> void* { - // TODO(bdero): Return VkImage handles - return reinterpret_cast(context)->GetNextImage(); + vulkan_renderer_config_.get_next_image_callback = + [](void* context, + const FlutterFrameInfo* frame_info) -> FlutterVulkanImage { + VkImage image = + reinterpret_cast(context)->GetNextImage( + {static_cast(frame_info->size.width), + static_cast(frame_info->size.height)}); + return { + .struct_size = sizeof(FlutterVulkanImage), + .image = image, + }; }; - vulkan_renderer_config_->present_image_callback = [](void* context) -> void* { - return reinterpret_cast(context)->PresentImage(); + vulkan_renderer_config_.present_image_callback = + [](void* context, const FlutterVulkanImage* image) -> bool { + return reinterpret_cast(context)->PresentImage( + reinterpret_cast(image->image)); }; - #endif +#endif #ifdef SHELL_ENABLE_METAL InitializeMetalRendererConfig(); diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc index d8e42b63eec5a..266d69c747b83 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -8,9 +8,10 @@ #include "embedder.h" #include "flutter/fml/logging.h" -//#include -//"flutter/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h" +// #include +// "flutter/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h" +#include "flutter/vulkan/vulkan_device.h" #include "flutter/vulkan/vulkan_proc_table.h" #ifdef OS_MACOSX @@ -27,16 +28,28 @@ namespace testing { EmbedderTestContextVulkan::EmbedderTestContextVulkan(std::string assets_path) : EmbedderTestContext(assets_path) { vk_ = fml::MakeRefCounted(VULKAN_SO_PATH); - FML_DCHECK(vk_->HasAcquiredMandatoryProcAddresses()); + if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { + FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; + return; + } application_ = std::unique_ptr( new vulkan::VulkanApplication(*vk_, "Flutter Unittests", {})); - FML_DCHECK(application_->IsValid()); - FML_DCHECK(vk_->AreInstanceProcsSetup()); + if (!application_->IsValid()) { + FML_DLOG(ERROR) << "Failed to initialize basic Vulkan state."; + return; + } + if (!vk_->AreInstanceProcsSetup()) { + FML_DLOG(ERROR) << "Failed to acquire full proc table."; + return; + } logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); - FML_DCHECK(logical_device_ != nullptr); - FML_DCHECK(logical_device_->IsValid()); + if (!logical_device_ || !logical_device_->IsValid()) { + FML_DLOG(ERROR) << "Failed to create compatible logical device."; + return; + } + } EmbedderTestContextVulkan::~EmbedderTestContextVulkan() {} @@ -54,6 +67,16 @@ size_t EmbedderTestContextVulkan::GetSurfacePresentCount() const { return present_count_; } +VkImage EmbedderTestContextVulkan::GetNextImage(const SkISize& size) { + assert(false); // TODO(bdero) + return nullptr; +} + +bool EmbedderTestContextVulkan::PresentImage(VkImage image) { + assert(false); // TODO(bdero) + return false; +} + EmbedderTestContextType EmbedderTestContextVulkan::GetContextType() const { return EmbedderTestContextType::kVulkanContext; } diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.h b/shell/platform/embedder/tests/embedder_test_context_vulkan.h index babdccdfcaa80..2e1d7ead06919 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.h +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONTEXT_VULKAN_H_ #define FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONTEXT_VULKAN_H_ +#include "tests/embedder_test_context.h" #include "vulkan/vulkan_application.h" namespace flutter { @@ -25,6 +26,10 @@ class EmbedderTestContextVulkan : public EmbedderTestContext { // |EmbedderTestContext| void SetupCompositor() override; + VkImage GetNextImage(const SkISize& size); + + bool PresentImage(VkImage image); + private: // This allows the builder to access the hooks. friend class EmbedderConfigBuilder; diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 2d3c52a99e93d..ffa1272bb5ba3 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -32,9 +32,7 @@ #include "flutter/shell/platform/embedder/tests/embedder_unittests_util.h" #include "flutter/testing/assertions_skia.h" #include "flutter/testing/test_gl_surface.h" -#include "flutter/testing/test_vulkan_context.h" #include "flutter/testing/testing.h" -#include "flutter/vulkan/vulkan_proc_table.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/src/gpu/gl/GrGLDefines.h" #include "third_party/tonic/converter/dart_converter.h" @@ -44,20 +42,10 @@ namespace testing { using EmbedderTest = testing::EmbedderTest; -//------------------------------------------------------------------------------ -/// This is a sanity check to ensure Swiftshader Vulkan is working. Once Vulkan -/// support lands in the embedder API, it'll be tested via a new -/// EmbedderTestContext type/config. -/// -//TEST_F(EmbedderTest, CanInitializeTestVulkanContext) { -// TestVulkanContext ctx; -// ASSERT_TRUE(ctx.IsValid()); -//} - -//TEST_F(EmbedderTest, CanGetVulkanEmbedderContext) { -// auto& context = GetEmbedderContext(EmbedderTestContextType::kVulkanContext); -// EmbedderConfigBuilder builder(context); -//} +TEST_F(EmbedderTest, CanGetVulkanEmbedderContext) { + auto& context = GetEmbedderContext(EmbedderTestContextType::kVulkanContext); + EmbedderConfigBuilder builder(context); +} TEST_F(EmbedderTest, CanCreateOpenGLRenderingEngine) { EmbedderConfigBuilder builder( diff --git a/testing/BUILD.gn b/testing/BUILD.gn index 9ae50f47e8d00..edf42b2bddc2d 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn @@ -125,11 +125,6 @@ if (enable_unittests) { source_set("vulkan") { testonly = true - sources = [ - "test_vulkan_context.cc", - "test_vulkan_context.h", - ] - defines = [ "TEST_VULKAN_PROCS" ] deps = [ diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc deleted file mode 100644 index 36c30989d08d0..0000000000000 --- a/testing/test_vulkan_context.cc +++ /dev/null @@ -1,52 +0,0 @@ -// 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. - -#include "test_vulkan_context.h" - -#include "flutter/vulkan/vulkan_proc_table.h" - -#ifdef FML_OS_MACOSX -#define VULKAN_SO_PATH "libvk_swiftshader.dylib" -#elif FML_OS_WIN -#define VULKAN_SO_PATH "vk_swiftshader.dll" -#else -#define VULKAN_SO_PATH "libvk_swiftshader.so" -#endif - -namespace flutter { - -TestVulkanContext::TestVulkanContext() : valid_(false) { - vk_ = fml::MakeRefCounted(VULKAN_SO_PATH); - if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { - FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; - return; - } - - application_ = std::unique_ptr( - new vulkan::VulkanApplication(*vk_, "Flutter Unittests", {})); - if (!application_->IsValid()) { - FML_DLOG(ERROR) << "Failed to initialize basic Vulkan state."; - return; - } - if (!vk_->AreInstanceProcsSetup()) { - FML_DLOG(ERROR) << "Failed to acquire full proc table."; - return; - } - - logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); - if (!logical_device_ || !logical_device_->IsValid()) { - FML_DLOG(ERROR) << "Failed to create compatible logical device."; - return; - } - - valid_ = true; -} - -TestVulkanContext::~TestVulkanContext() = default; - -bool TestVulkanContext::IsValid() { - return valid_; -} - -} // namespace flutter diff --git a/testing/test_vulkan_context.h b/testing/test_vulkan_context.h deleted file mode 100644 index 5d79971809dd3..0000000000000 --- a/testing/test_vulkan_context.h +++ /dev/null @@ -1,33 +0,0 @@ -// 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. - -#ifndef FLUTTER_TESTING_TEST_VULKAN_CONTEXT_H_ -#define FLUTTER_TESTING_TEST_VULKAN_CONTEXT_H_ - -#include "flutter/vulkan/vulkan_application.h" -#include "flutter/vulkan/vulkan_device.h" -#include "flutter/vulkan/vulkan_proc_table.h" - -namespace flutter { - -/// @brief Utility class to create a Vulkan device context, a corresponding -/// Skia context, and device resources. -class TestVulkanContext { - public: - TestVulkanContext(); - ~TestVulkanContext(); - bool IsValid(); - - private: - bool valid_ = false; - fml::RefPtr vk_; - std::unique_ptr application_; - std::unique_ptr logical_device_; - - FML_DISALLOW_COPY_AND_ASSIGN(TestVulkanContext); -}; - -} // namespace flutter - -#endif // FLUTTER_TESTING_TEST_VULKAN_CONTEXT_H_ diff --git a/vulkan/vulkan_proc_table.cc b/vulkan/vulkan_proc_table.cc index 535185e0a8f8a..99f34458e50f4 100644 --- a/vulkan/vulkan_proc_table.cc +++ b/vulkan/vulkan_proc_table.cc @@ -169,7 +169,11 @@ bool VulkanProcTable::OpenLibraryHandle(const char* path) { #else // VULKAN_LINK_STATICALLY handle_ = fml::NativeLibrary::Create(path); #endif // VULKAN_LINK_STATICALLY - return !!handle_; + if (!handle_) { + FML_DLOG(WARNING) << "Could not open Vulkan library handle: " << path; + return false; + } + return true; } bool VulkanProcTable::CloseLibraryHandle() { From a6a78f9b638f6f7363b213f9bb682fc131ed0dbe Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 18 Nov 2021 01:35:11 -0800 Subject: [PATCH 07/60] Build fixes --- shell/gpu/gpu_surface_vulkan.cc | 2 +- .../embedder/tests/embedder_config_builder.cc | 3 +-- vulkan/vulkan_device.cc | 2 +- vulkan/vulkan_proc_table.cc | 14 +++++++------- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/shell/gpu/gpu_surface_vulkan.cc b/shell/gpu/gpu_surface_vulkan.cc index 722d0bb2bfcce..d7537b4d35899 100644 --- a/shell/gpu/gpu_surface_vulkan.cc +++ b/shell/gpu/gpu_surface_vulkan.cc @@ -111,7 +111,7 @@ sk_sp GPUSurfaceVulkan::CreateSurfaceFromVulkanImage( SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); return SkSurface::MakeFromBackendTexture( - skia_context_.get(), // context + skia_context_.get(), // context backend_texture, // back-end texture kTopLeft_GrSurfaceOrigin, // surface origin 1, // sample count diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index fd63a16fc99a0..50cd6681d7b14 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -95,8 +95,7 @@ EmbedderConfigBuilder::EmbedderConfigBuilder( [](void* context, FlutterVulkanInstanceHandle instance, const char* name) -> void* { return reinterpret_cast(context) - ->vk_->GetInstanceProcAddr(reinterpret_cast(instance), - name); + ->vk_.GetInstanceProcAddr(reinterpret_cast(instance), name); }; vulkan_renderer_config_.get_next_image_callback = [](void* context, diff --git a/vulkan/vulkan_device.cc b/vulkan/vulkan_device.cc index 3aacdb30ae488..e58dd6e7db37f 100644 --- a/vulkan/vulkan_device.cc +++ b/vulkan/vulkan_device.cc @@ -136,8 +136,8 @@ VulkanDevice::VulkanDevice(VulkanProcTable& p_vk, : vk(p_vk), physical_device_(std::move(physical_device)), device_(std::move(device)), - graphics_queue_index_(queue_family_index), queue_(std::move(queue)), + graphics_queue_index_(queue_family_index), valid_(false) { if (!physical_device_ || !vk.AreInstanceProcsSetup()) { return; diff --git a/vulkan/vulkan_proc_table.cc b/vulkan/vulkan_proc_table.cc index 99f34458e50f4..2c647494def32 100644 --- a/vulkan/vulkan_proc_table.cc +++ b/vulkan/vulkan_proc_table.cc @@ -18,6 +18,7 @@ VulkanProcTable::VulkanProcTable() : VulkanProcTable("libvulkan.so"){}; VulkanProcTable::VulkanProcTable(const char* so_path) : handle_(nullptr), acquired_mandatory_proc_addresses_(false) { + FML_DLOG(WARNING) << "Cowabunga"; acquired_mandatory_proc_addresses_ = OpenLibraryHandle(so_path) && SetupGetInstanceProcAddress() && SetupLoaderProcAddresses(); @@ -55,14 +56,13 @@ bool VulkanProcTable::SetupGetInstanceProcAddress() { return true; } - GetInstanceProcAddr = + GetInstanceProcAddr = reinterpret_cast( #if VULKAN_LINK_STATICALLY - &vkGetInstanceProcAddr; -#else // VULKAN_LINK_STATICALLY - reinterpret_cast(const_cast( - handle_->ResolveSymbol("vkGetInstanceProcAddr"))); + &vkGetInstanceProcAddr +#else // VULKAN_LINK_STATICALLY + const_cast(handle_->ResolveSymbol("vkGetInstanceProcAddr")) #endif // VULKAN_LINK_STATICALLY - + ); if (!GetInstanceProcAddr) { FML_DLOG(WARNING) << "Could not acquire vkGetInstanceProcAddr."; return false; @@ -166,7 +166,7 @@ bool VulkanProcTable::SetupDeviceProcAddresses( bool VulkanProcTable::OpenLibraryHandle(const char* path) { #if VULKAN_LINK_STATICALLY handle_ = fml::NativeLibrary::CreateForCurrentProcess(); -#else // VULKAN_LINK_STATICALLY +#else // VULKAN_LINK_STATICALLY handle_ = fml::NativeLibrary::Create(path); #endif // VULKAN_LINK_STATICALLY if (!handle_) { From 73fb9a952d69d2d607d72a9ec3b2339798c91732 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 18 Nov 2021 01:48:15 -0800 Subject: [PATCH 08/60] Format --- shell/platform/embedder/embedder_surface_vulkan.cc | 6 +++--- shell/platform/embedder/tests/embedder_config_builder.cc | 3 ++- shell/platform/embedder/tests/embedder_config_builder.h | 4 ++-- .../platform/embedder/tests/embedder_test_context_vulkan.cc | 1 - .../platform/embedder/tests/embedder_test_context_vulkan.h | 1 - vulkan/vulkan_proc_table.h | 6 ++---- 6 files changed, 9 insertions(+), 12 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index c4a8ac0fdc121..c9620245ddfa9 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -53,17 +53,17 @@ EmbedderSurfaceVulkan::~EmbedderSurfaceVulkan() = default; // |GPUSurfaceVulkanDelegate| const vulkan::VulkanProcTable& EmbedderSurfaceVulkan::vk() { - return vk_; + return vk_; } // |GPUSurfaceVulkanDelegate| VkImage EmbedderSurfaceVulkan::AcquireImage(const SkISize& size) { - return vulkan_dispatch_table_.get_next_image(size); + return vulkan_dispatch_table_.get_next_image(size); } // |GPUSurfaceVulkanDelegate| bool EmbedderSurfaceVulkan::PresentImage(VkImage image) { - return vulkan_dispatch_table_.present_image(image); + return vulkan_dispatch_table_.present_image(image); } // |EmbedderSurface| diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 50cd6681d7b14..fd63a16fc99a0 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -95,7 +95,8 @@ EmbedderConfigBuilder::EmbedderConfigBuilder( [](void* context, FlutterVulkanInstanceHandle instance, const char* name) -> void* { return reinterpret_cast(context) - ->vk_.GetInstanceProcAddr(reinterpret_cast(instance), name); + ->vk_->GetInstanceProcAddr(reinterpret_cast(instance), + name); }; vulkan_renderer_config_.get_next_image_callback = [](void* context, diff --git a/shell/platform/embedder/tests/embedder_config_builder.h b/shell/platform/embedder/tests/embedder_config_builder.h index be7f4282824ae..0f4fce33b2b7e 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.h +++ b/shell/platform/embedder/tests/embedder_config_builder.h @@ -119,9 +119,9 @@ class EmbedderConfigBuilder { #ifdef SHELL_ENABLE_GL FlutterOpenGLRendererConfig opengl_renderer_config_ = {}; #endif -//#ifdef SHELL_ENABLE_VULKAN +#ifdef SHELL_ENABLE_VULKAN FlutterVulkanRendererConfig vulkan_renderer_config_ = {}; -//#endif +#endif #ifdef SHELL_ENABLE_METAL void InitializeMetalRendererConfig(); FlutterMetalRendererConfig metal_renderer_config_ = {}; diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc index 266d69c747b83..bbe76e5ac7fcc 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -49,7 +49,6 @@ EmbedderTestContextVulkan::EmbedderTestContextVulkan(std::string assets_path) FML_DLOG(ERROR) << "Failed to create compatible logical device."; return; } - } EmbedderTestContextVulkan::~EmbedderTestContextVulkan() {} diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.h b/shell/platform/embedder/tests/embedder_test_context_vulkan.h index 2e1d7ead06919..60a8c24f2809b 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.h +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.h @@ -39,7 +39,6 @@ class EmbedderTestContextVulkan : public EmbedderTestContext { std::unique_ptr logical_device_; SkISize surface_size_ = SkISize::MakeEmpty(); - //std::unique_ptr vulkan_context_; size_t present_count_ = 0; void SetupSurface(SkISize surface_size) override; diff --git a/vulkan/vulkan_proc_table.h b/vulkan/vulkan_proc_table.h index d4f623452da53..93b4d0a3bfdd2 100644 --- a/vulkan/vulkan_proc_table.h +++ b/vulkan/vulkan_proc_table.h @@ -51,8 +51,7 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { VulkanProcTable(); explicit VulkanProcTable(const char* so_path); explicit VulkanProcTable( - std::function - get_instance_proc_addr); + std::function get_instance_proc_addr); ~VulkanProcTable(); bool HasAcquiredMandatoryProcAddresses() const; @@ -69,8 +68,7 @@ class VulkanProcTable : public fml::RefCountedThreadSafe { GrVkGetProc CreateSkiaGetProc() const; - std::function - GetInstanceProcAddr = nullptr; + std::function GetInstanceProcAddr = nullptr; #define DEFINE_PROC(name) Proc name; From 5bcd4df32cb4fd1ff45664dd04c7b342f4f6e9e7 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 18 Nov 2021 01:54:35 -0800 Subject: [PATCH 09/60] embedder_test.cc format --- shell/platform/embedder/tests/embedder_test.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_test.cc b/shell/platform/embedder/tests/embedder_test.cc index 0189a5c0457c9..9a315dec3c415 100644 --- a/shell/platform/embedder/tests/embedder_test.cc +++ b/shell/platform/embedder/tests/embedder_test.cc @@ -34,11 +34,12 @@ EmbedderTestContext& EmbedderTest::GetEmbedderContext( std::make_unique( GetFixturesDirectory()); break; +#ifdef SHELL_ENABLE_VULKAN case EmbedderTestContextType::kVulkanContext: embedder_contexts_[type] = - std::make_unique( - GetFixturesDirectory()); + std::make_unique(GetFixturesDirectory()); break; +#endif #ifdef SHELL_ENABLE_GL case EmbedderTestContextType::kOpenGLContext: embedder_contexts_[type] = From 78a5f5ae22633c3e47e35e7e8a551bfd1eebbd30 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 18 Nov 2021 02:27:47 -0800 Subject: [PATCH 10/60] Licenses --- ci/licenses_golden/licenses_flutter | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 451829e08617e..608207369dff5 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1365,6 +1365,8 @@ FILE: ../../../flutter/shell/platform/embedder/embedder_surface_metal.h FILE: ../../../flutter/shell/platform/embedder/embedder_surface_metal.mm FILE: ../../../flutter/shell/platform/embedder/embedder_surface_software.cc FILE: ../../../flutter/shell/platform/embedder/embedder_surface_software.h +FILE: ../../../flutter/shell/platform/embedder/embedder_surface_vulkan.cc +FILE: ../../../flutter/shell/platform/embedder/embedder_surface_vulkan.h FILE: ../../../flutter/shell/platform/embedder/embedder_task_runner.cc FILE: ../../../flutter/shell/platform/embedder/embedder_task_runner.h FILE: ../../../flutter/shell/platform/embedder/embedder_thread_host.cc From a230d2d0b960b05bc550713fd367c4449bc66649 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 18 Nov 2021 03:49:27 -0800 Subject: [PATCH 11/60] Gate vk config initialization --- .../embedder/tests/embedder_config_builder.cc | 110 +++++++++++------- .../embedder/tests/embedder_config_builder.h | 5 +- vulkan/vulkan_proc_table.cc | 1 - 3 files changed, 68 insertions(+), 48 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index fd63a16fc99a0..201b066bf39a4 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -13,10 +13,10 @@ #include "flutter/shell/platform/embedder/tests/embedder_test_context_gl.h" #endif -//#ifdef SHELL_ENABLE_VULKAN +#ifdef SHELL_ENABLE_VULKAN #include "flutter/shell/platform/embedder/tests/embedder_test_context_vulkan.h" #include "flutter/vulkan/vulkan_device.h" -//#endif +#endif #ifdef SHELL_ENABLE_METAL #include "flutter/shell/platform/embedder/tests/embedder_test_context_metal.h" @@ -74,53 +74,14 @@ EmbedderConfigBuilder::EmbedderConfigBuilder( }; #endif -#ifdef SHELL_ENABLE_VULKAN - vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); - vulkan_renderer_config_.instance = - static_cast(context) - .application_->GetInstance(); - vulkan_renderer_config_.physical_device = - static_cast(context) - .logical_device_->GetPhysicalDeviceHandle(); - vulkan_renderer_config_.device = - static_cast(context) - .logical_device_->GetHandle(); - vulkan_renderer_config_.queue_family_index = - static_cast(context) - .logical_device_->GetGraphicsQueueIndex(); - vulkan_renderer_config_.queue = - static_cast(context) - .logical_device_->GetQueueHandle(); - vulkan_renderer_config_.get_instance_proc_address_callback = - [](void* context, FlutterVulkanInstanceHandle instance, - const char* name) -> void* { - return reinterpret_cast(context) - ->vk_->GetInstanceProcAddr(reinterpret_cast(instance), - name); - }; - vulkan_renderer_config_.get_next_image_callback = - [](void* context, - const FlutterFrameInfo* frame_info) -> FlutterVulkanImage { - VkImage image = - reinterpret_cast(context)->GetNextImage( - {static_cast(frame_info->size.width), - static_cast(frame_info->size.height)}); - return { - .struct_size = sizeof(FlutterVulkanImage), - .image = image, - }; - }; - vulkan_renderer_config_.present_image_callback = - [](void* context, const FlutterVulkanImage* image) -> bool { - return reinterpret_cast(context)->PresentImage( - reinterpret_cast(image->image)); - }; -#endif - #ifdef SHELL_ENABLE_METAL InitializeMetalRendererConfig(); #endif +#ifdef SHELL_ENABLE_VULKAN + InitializeVulkanRendererConfig(); +#endif + software_renderer_config_.struct_size = sizeof(FlutterSoftwareRendererConfig); software_renderer_config_.surface_present_callback = [](void* context, const void* allocation, size_t row_bytes, @@ -218,6 +179,14 @@ void EmbedderConfigBuilder::SetMetalRendererConfig(SkISize surface_size) { #endif } +void EmbedderConfigBuilder::SetVulkanRendererConfig(SkISize surface_size) { +#ifdef SHELL_ENABLE_VULKAN + renderer_config_.type = FlutterRendererType::kVulkan; + renderer_config_.vulkan = vulkan_renderer_config_; + context_.SetupSurface(surface_size); +#endif +} + void EmbedderConfigBuilder::SetAssetsPath() { project_args_.assets_path = context_.GetAssetsPath().c_str(); } @@ -476,5 +445,56 @@ void EmbedderConfigBuilder::InitializeMetalRendererConfig() { #endif // SHELL_ENABLE_METAL +#ifdef SHELL_ENABLE_VULKAN + +void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { + if (context_.GetContextType() != EmbedderTestContextType::kVulkanContext) { + return; + } + + vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); + vulkan_renderer_config_.instance = + static_cast(context_) + .application_->GetInstance(); + vulkan_renderer_config_.physical_device = + static_cast(context_) + .logical_device_->GetPhysicalDeviceHandle(); + vulkan_renderer_config_.device = + static_cast(context_) + .logical_device_->GetHandle(); + vulkan_renderer_config_.queue_family_index = + static_cast(context_) + .logical_device_->GetGraphicsQueueIndex(); + vulkan_renderer_config_.queue = + static_cast(context_) + .logical_device_->GetQueueHandle(); + vulkan_renderer_config_.get_instance_proc_address_callback = + [](void* context, FlutterVulkanInstanceHandle instance, + const char* name) -> void* { + return reinterpret_cast(context) + ->vk_->GetInstanceProcAddr(reinterpret_cast(instance), + name); + }; + vulkan_renderer_config_.get_next_image_callback = + [](void* context, + const FlutterFrameInfo* frame_info) -> FlutterVulkanImage { + VkImage image = + reinterpret_cast(context)->GetNextImage( + {static_cast(frame_info->size.width), + static_cast(frame_info->size.height)}); + return { + .struct_size = sizeof(FlutterVulkanImage), + .image = image, + }; + }; + vulkan_renderer_config_.present_image_callback = + [](void* context, const FlutterVulkanImage* image) -> bool { + return reinterpret_cast(context)->PresentImage( + reinterpret_cast(image->image)); + }; +} + +#endif + } // namespace testing } // namespace flutter diff --git a/shell/platform/embedder/tests/embedder_config_builder.h b/shell/platform/embedder/tests/embedder_config_builder.h index 0f4fce33b2b7e..4cdf2a33d8b6e 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.h +++ b/shell/platform/embedder/tests/embedder_config_builder.h @@ -49,10 +49,10 @@ class EmbedderConfigBuilder { void SetOpenGLRendererConfig(SkISize surface_size); - void SetVulkanRendererConfig(SkISize surface_size); - void SetMetalRendererConfig(SkISize surface_size); + void SetVulkanRendererConfig(SkISize surface_size); + // Used to explicitly set an `open_gl.fbo_callback`. Using this method will // cause your test to fail since the ctor for this class sets // `open_gl.fbo_callback_with_frame_info`. This method exists as a utility to @@ -120,6 +120,7 @@ class EmbedderConfigBuilder { FlutterOpenGLRendererConfig opengl_renderer_config_ = {}; #endif #ifdef SHELL_ENABLE_VULKAN + void InitializeVulkanRendererConfig(); FlutterVulkanRendererConfig vulkan_renderer_config_ = {}; #endif #ifdef SHELL_ENABLE_METAL diff --git a/vulkan/vulkan_proc_table.cc b/vulkan/vulkan_proc_table.cc index 2c647494def32..f1ccbe88586b2 100644 --- a/vulkan/vulkan_proc_table.cc +++ b/vulkan/vulkan_proc_table.cc @@ -18,7 +18,6 @@ VulkanProcTable::VulkanProcTable() : VulkanProcTable("libvulkan.so"){}; VulkanProcTable::VulkanProcTable(const char* so_path) : handle_(nullptr), acquired_mandatory_proc_addresses_(false) { - FML_DLOG(WARNING) << "Cowabunga"; acquired_mandatory_proc_addresses_ = OpenLibraryHandle(so_path) && SetupGetInstanceProcAddress() && SetupLoaderProcAddresses(); From 71465a300e2ccfd778d12360e2e4207c11dc22d0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 19 Nov 2021 16:10:10 -0800 Subject: [PATCH 12/60] Explicit constructor calls for VulkanHandle --- shell/platform/embedder/embedder_surface_vulkan.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index c9620245ddfa9..da0c162d2b649 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -21,7 +21,11 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( VulkanDispatchTable vulkan_dispatch_table, std::shared_ptr external_view_embedder) : vk_(vulkan_dispatch_table.get_instance_proc_address), - device_(vk_, physical_device, device, queue_family_index, queue), + device_(vk_, + vulkan::VulkanHandle{physical_device}, + vulkan::VulkanHandle{device}, + queue_family_index, + vulkan::VulkanHandle{queue}), vulkan_dispatch_table_(vulkan_dispatch_table), external_view_embedder_(external_view_embedder) { // Make sure all required members of the dispatch table are checked. @@ -31,8 +35,8 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( return; } - vk_.SetupInstanceProcAddresses(instance); - vk_.SetupDeviceProcAddresses(device); + vk_.SetupInstanceProcAddresses(vulkan::VulkanHandle{instance}); + vk_.SetupDeviceProcAddresses(vulkan::VulkanHandle{device}); if (!vk_.IsValid()) { FML_LOG(ERROR) << "VulkanProcTable invalid."; return; From 9e44701a0884657a9cc1676e5d632195237388f5 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 19 Nov 2021 20:58:13 -0800 Subject: [PATCH 13/60] Add test context that can be passed around, create a skia context for snapshotting surfaces, create a Vulkan image wrapper for making an SkSurfaces --- .../embedder/tests/embedder_config_builder.cc | 14 +-- .../tests/embedder_test_context_vulkan.cc | 33 +----- .../tests/embedder_test_context_vulkan.h | 14 ++- testing/BUILD.gn | 8 ++ testing/test_vulkan_context.cc | 100 ++++++++++++++++++ testing/test_vulkan_context.h | 44 ++++++++ testing/test_vulkan_surface.cc | 97 +++++++++++++++++ testing/test_vulkan_surface.h | 34 ++++++ 8 files changed, 297 insertions(+), 47 deletions(-) create mode 100644 testing/test_vulkan_context.cc create mode 100644 testing/test_vulkan_context.h create mode 100644 testing/test_vulkan_surface.cc create mode 100644 testing/test_vulkan_surface.h diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 201b066bf39a4..9a31fdf3ee486 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -455,25 +455,25 @@ void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); vulkan_renderer_config_.instance = static_cast(context_) - .application_->GetInstance(); + .context_.application_->GetInstance(); vulkan_renderer_config_.physical_device = static_cast(context_) - .logical_device_->GetPhysicalDeviceHandle(); + .context_.device_->GetPhysicalDeviceHandle(); vulkan_renderer_config_.device = static_cast(context_) - .logical_device_->GetHandle(); + .context_.device_->GetHandle(); vulkan_renderer_config_.queue_family_index = static_cast(context_) - .logical_device_->GetGraphicsQueueIndex(); + .context_.device_->GetGraphicsQueueIndex(); vulkan_renderer_config_.queue = static_cast(context_) - .logical_device_->GetQueueHandle(); + .context_.device_->GetQueueHandle(); vulkan_renderer_config_.get_instance_proc_address_callback = [](void* context, FlutterVulkanInstanceHandle instance, const char* name) -> void* { return reinterpret_cast(context) - ->vk_->GetInstanceProcAddr(reinterpret_cast(instance), - name); + ->context_.vk_->GetInstanceProcAddr( + reinterpret_cast(instance), name); }; vulkan_renderer_config_.get_next_image_callback = [](void* context, diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc index bbe76e5ac7fcc..93ea21903f27f 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -14,42 +14,11 @@ #include "flutter/vulkan/vulkan_device.h" #include "flutter/vulkan/vulkan_proc_table.h" -#ifdef OS_MACOSX -#define VULKAN_SO_PATH "libvk_swiftshader.dylib" -#elif OS_WIN -#define VULKAN_SO_PATH "vk_swiftshader.dll" -#else -#define VULKAN_SO_PATH "libvk_swiftshader.so" -#endif - namespace flutter { namespace testing { EmbedderTestContextVulkan::EmbedderTestContextVulkan(std::string assets_path) - : EmbedderTestContext(assets_path) { - vk_ = fml::MakeRefCounted(VULKAN_SO_PATH); - if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { - FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; - return; - } - - application_ = std::unique_ptr( - new vulkan::VulkanApplication(*vk_, "Flutter Unittests", {})); - if (!application_->IsValid()) { - FML_DLOG(ERROR) << "Failed to initialize basic Vulkan state."; - return; - } - if (!vk_->AreInstanceProcsSetup()) { - FML_DLOG(ERROR) << "Failed to acquire full proc table."; - return; - } - - logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); - if (!logical_device_ || !logical_device_->IsValid()) { - FML_DLOG(ERROR) << "Failed to create compatible logical device."; - return; - } -} + : EmbedderTestContext(assets_path), context_() {} EmbedderTestContextVulkan::~EmbedderTestContextVulkan() {} diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.h b/shell/platform/embedder/tests/embedder_test_context_vulkan.h index 60a8c24f2809b..8effcbe1e7b5c 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.h +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.h @@ -5,8 +5,9 @@ #ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONTEXT_VULKAN_H_ #define FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONTEXT_VULKAN_H_ -#include "tests/embedder_test_context.h" -#include "vulkan/vulkan_application.h" +#include "flutter/shell/platform/embedder/tests/embedder_test_context.h" +#include "flutter/testing/test_vulkan_context.h" +#include "flutter/vulkan/vulkan_application.h" namespace flutter { namespace testing { @@ -31,18 +32,15 @@ class EmbedderTestContextVulkan : public EmbedderTestContext { bool PresentImage(VkImage image); private: - // This allows the builder to access the hooks. - friend class EmbedderConfigBuilder; - - fml::RefPtr vk_; - std::unique_ptr application_; - std::unique_ptr logical_device_; + TestVulkanContext context_; SkISize surface_size_ = SkISize::MakeEmpty(); size_t present_count_ = 0; void SetupSurface(SkISize surface_size) override; + friend class EmbedderConfigBuilder; + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderTestContextVulkan); }; diff --git a/testing/BUILD.gn b/testing/BUILD.gn index edf42b2bddc2d..394b9d74db3d0 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn @@ -125,11 +125,19 @@ if (enable_unittests) { source_set("vulkan") { testonly = true + sources = [ + "test_vulkan_context.cc", + "test_vulkan_context.h", + "test_vulkan_surface.cc", + "test_vulkan_surface.h", + ] + defines = [ "TEST_VULKAN_PROCS" ] deps = [ ":skia", "//flutter/fml", + "//flutter/shell/common", "//flutter/vulkan", ] diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc new file mode 100644 index 0000000000000..e96f770039805 --- /dev/null +++ b/testing/test_vulkan_context.cc @@ -0,0 +1,100 @@ +// 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. + +#include + +#include "flutter/testing/test_vulkan_context.h" +#include "flutter/fml/logging.h" +#include "flutter/shell/common/context_options.h" + +#include "include/gpu/GrDirectContext.h" +#include "third_party/skia/include/core/SkSurface.h" + +#ifdef OS_MACOSX +#define VULKAN_SO_PATH "libvk_swiftshader.dylib" +#elif OS_WIN +#define VULKAN_SO_PATH "vk_swiftshader.dll" +#else +#define VULKAN_SO_PATH "libvk_swiftshader.so" +#endif + +namespace flutter { +namespace testing { + +TestVulkanContext::TestVulkanContext() { + // --------------------------------------------------------------------------- + // Initialize basic Vulkan state using the Swiftshader ICD. + // --------------------------------------------------------------------------- + + vk_ = fml::MakeRefCounted(VULKAN_SO_PATH); + if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { + FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; + return; + } + + application_ = std::unique_ptr( + new vulkan::VulkanApplication(*vk_, "Flutter Unittests", {})); + if (!application_->IsValid()) { + FML_DLOG(ERROR) << "Failed to initialize basic Vulkan state."; + return; + } + if (!vk_->AreInstanceProcsSetup()) { + FML_DLOG(ERROR) << "Failed to acquire full proc table."; + return; + } + + device_ = application_->AcquireFirstCompatibleLogicalDevice(); + if (!device_ || !device_->IsValid()) { + FML_DLOG(ERROR) << "Failed to create compatible logical device."; + return; + } + + // --------------------------------------------------------------------------- + // Create a Skia context. + // For creating SkSurfaces from VkImages and snapshotting them, etc. + // --------------------------------------------------------------------------- + + uint32_t skia_features = 0; + if (!device_->GetPhysicalDeviceFeaturesSkia(&skia_features)) { + FML_LOG(ERROR) << "Failed to get physical device features."; + + return; + } + + auto get_proc = vk_->CreateSkiaGetProc(); + if (get_proc == nullptr) { + FML_LOG(ERROR) << "Failed to create Vulkan getProc for Skia."; + return; + } + + GrVkBackendContext backend_context = { + .fInstance = application_->GetInstance(), + .fPhysicalDevice = device_->GetPhysicalDeviceHandle(), + .fDevice = device_->GetHandle(), + .fQueue = device_->GetQueueHandle(), + .fGraphicsQueueIndex = device_->GetGraphicsQueueIndex(), + .fMinAPIVersion = VK_MAKE_VERSION(1, 0, 0), + .fMaxAPIVersion = VK_MAKE_VERSION(1, 0, 0), + .fFeatures = skia_features, + .fGetProc = get_proc, + .fOwnsInstanceAndDevice = false, + }; + + GrContextOptions options = + MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kVulkan); + options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; + context_ = GrDirectContext::MakeVulkan(backend_context, options); +} + +VkImage TestVulkanContext::CreateImage(const SkISize& size) const { + assert(false); // TODO(bdero) + return nullptr; +} + +sk_sp TestVulkanContext::GetGrDirectContext() const { + return context_; +} + +} // namespace testing +} // namespace flutter diff --git a/testing/test_vulkan_context.h b/testing/test_vulkan_context.h new file mode 100644 index 0000000000000..8e4b4eb57f159 --- /dev/null +++ b/testing/test_vulkan_context.h @@ -0,0 +1,44 @@ +// 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. + +#ifndef FLUTTER_TESTING_TEST_VULKAN_CONTEXT_H_ +#define FLUTTER_TESTING_TEST_VULKAN_CONTEXT_H_ + +#include "flutter/fml/macros.h" +#include "flutter/fml/memory/ref_ptr.h" +#include "flutter/vulkan/vulkan_application.h" +#include "flutter/vulkan/vulkan_device.h" +#include "flutter/vulkan/vulkan_proc_table.h" + +#include "third_party/skia/include/core/SkSize.h" +#include "third_party/skia/include/gpu/GrDirectContext.h" + +namespace flutter { +namespace testing { + +class TestVulkanContext { + public: + TestVulkanContext(); + + VkImage CreateImage(const SkISize& size) const; + + sk_sp GetGrDirectContext() const; + + private: + fml::RefPtr vk_; + std::unique_ptr application_; + std::unique_ptr device_; + + sk_sp context_; + + friend class EmbedderTestContextVulkan; + friend class EmbedderConfigBuilder; + + FML_DISALLOW_COPY_AND_ASSIGN(TestVulkanContext); +}; + +} // namespace testing +} // namespace flutter + +#endif // FLUTTER_TESTING_TEST_VULKAN_CONTEXT_H_ diff --git a/testing/test_vulkan_surface.cc b/testing/test_vulkan_surface.cc new file mode 100644 index 0000000000000..76d440638ceaf --- /dev/null +++ b/testing/test_vulkan_surface.cc @@ -0,0 +1,97 @@ +// 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. + +#include "flutter/testing/test_vulkan_surface.h" +#include "flutter/fml/logging.h" +#include "flutter/testing/test_vulkan_context.h" + +#include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/core/SkSurfaceProps.h" + +namespace flutter { +namespace testing { + +TestVulkanSurface::TestVulkanSurface(const TestVulkanContext& context, + const SkISize& surface_size) { + VkImage image = context.CreateImage(surface_size); + + if (!image) { + FML_LOG(ERROR) << "Could not create VkImage."; + return; + } + + GrVkImageInfo image_info = { + .fImage = static_cast(image), + .fImageTiling = VK_IMAGE_TILING_OPTIMAL, + .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .fFormat = VK_FORMAT_R8G8B8A8_UNORM, + .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT, + .fSampleCount = 1, + .fLevelCount = 1, + }; + GrBackendTexture backend_texture(surface_size.width(), // + surface_size.height(), // + image_info // + ); + + SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); + + surface_ = SkSurface::MakeFromBackendTexture( + context.GetGrDirectContext().get(), // context + backend_texture, // back-end texture + kTopLeft_GrSurfaceOrigin, // surface origin + 1, // sample count + kRGBA_8888_SkColorType, // color type + SkColorSpace::MakeSRGB(), // color space + &surface_properties, // surface properties + nullptr, // release proc + nullptr // release context + ); + + if (!surface_) { + FML_LOG(ERROR) + << "Could not wrap VkImage as an SkSurface Vulkan render texture."; + return; + } +} + +bool TestVulkanSurface::IsValid() const { + return surface_ != nullptr; +} + +sk_sp TestVulkanSurface::GetSurfaceSnapshot() const { + if (!IsValid()) { + return nullptr; + } + + if (!surface_) { + FML_LOG(ERROR) << "Aborting snapshot because of on-screen surface " + "acquisition failure."; + return nullptr; + } + + auto device_snapshot = surface_->makeImageSnapshot(); + + if (!device_snapshot) { + FML_LOG(ERROR) << "Could not create the device snapshot while attempting " + "to snapshot the Vulkan surface."; + return nullptr; + } + + auto host_snapshot = device_snapshot->makeRasterImage(); + + if (!host_snapshot) { + FML_LOG(ERROR) << "Could not create the host snapshot while attempting to " + "snapshot the Vulkan surface."; + return nullptr; + } + + return host_snapshot; +} + +} // namespace testing +} // namespace flutter diff --git a/testing/test_vulkan_surface.h b/testing/test_vulkan_surface.h new file mode 100644 index 0000000000000..380b5ba9ab5b4 --- /dev/null +++ b/testing/test_vulkan_surface.h @@ -0,0 +1,34 @@ +// 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. + +#ifndef FLUTTER_TESTING_TEST_VULKAN_SURFACE_IMPL_H_ +#define FLUTTER_TESTING_TEST_VULKAN_SURFACE_IMPL_H_ + +#include "flutter/testing/test_vulkan_context.h" + +#include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/include/core/SkSize.h" +#include "third_party/skia/include/gpu/GrDirectContext.h" + +namespace flutter { + +namespace testing { + +class TestVulkanSurface { + public: + TestVulkanSurface(const TestVulkanContext& context, + const SkISize& surface_size); + + bool IsValid() const; + + sk_sp GetSurfaceSnapshot() const; + + private: + sk_sp surface_; +}; + +} // namespace testing +} // namespace flutter + +#endif // FLUTTER_TESTING_TEST_VULKAN_SURFACE_IMPL_H_ From 6da3ce24e8982b43f2bad0edff64f0fb4d68187d Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 23 Nov 2021 16:24:02 -0800 Subject: [PATCH 14/60] Format --- testing/test_vulkan_context.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index e96f770039805..6044b74e3d1b8 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -4,9 +4,9 @@ #include -#include "flutter/testing/test_vulkan_context.h" #include "flutter/fml/logging.h" #include "flutter/shell/common/context_options.h" +#include "flutter/testing/test_vulkan_context.h" #include "include/gpu/GrDirectContext.h" #include "third_party/skia/include/core/SkSurface.h" From fa462788d128c7f48f1805c4eccb485fc91fd7e9 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 23 Nov 2021 17:27:51 -0800 Subject: [PATCH 15/60] Fix extension init segfault --- .../embedder/embedder_surface_vulkan.cc | 32 ++++++++++--------- testing/test_vulkan_context.cc | 27 +++++++++------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index da0c162d2b649..8078c5cb4a9e7 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -7,6 +7,7 @@ #include "flutter/shell/common/shell_io_manager.h" #include "include/gpu/GrDirectContext.h" #include "include/gpu/vk/GrVkBackendContext.h" +#include "include/gpu/vk/GrVkExtensions.h" #include "shell/gpu/gpu_surface_vulkan.h" #include "shell/gpu/gpu_surface_vulkan_delegate.h" @@ -103,18 +104,21 @@ sk_sp EmbedderSurfaceVulkan::CreateGrContext( return nullptr; } - GrVkBackendContext backend_context = { - .fInstance = instance, - .fPhysicalDevice = device_.GetPhysicalDeviceHandle(), - .fDevice = device_.GetHandle(), - .fQueue = device_.GetQueueHandle(), - .fGraphicsQueueIndex = device_.GetGraphicsQueueIndex(), - .fMinAPIVersion = VK_MAKE_VERSION(1, 0, 0), - .fMaxAPIVersion = VK_MAKE_VERSION(1, 0, 0), - .fFeatures = skia_features, - .fGetProc = get_proc, - .fOwnsInstanceAndDevice = false, - }; + GrVkExtensions extensions; + + GrVkBackendContext backend_context = {}; + backend_context.fInstance = instance; + backend_context.fPhysicalDevice = device_.GetPhysicalDeviceHandle(); + backend_context.fDevice = device_.GetHandle(); + backend_context.fQueue = device_.GetQueueHandle(); + backend_context.fGraphicsQueueIndex = device_.GetGraphicsQueueIndex(); + backend_context.fMinAPIVersion = VK_MAKE_VERSION(1, 0, 0); + backend_context.fMaxAPIVersion = VK_MAKE_VERSION(1, 0, 0); + backend_context.fFeatures = skia_features; + backend_context.fVkExtensions = &extensions; + backend_context.fGetProc = get_proc; + backend_context.fOwnsInstanceAndDevice = false; + // TODO(bdero): Activate MEMORY_REQUIREMENTS_2 if available because VMA (the // allocator used by Skia) knows how to take advantage of these // features. @@ -122,11 +126,9 @@ sk_sp EmbedderSurfaceVulkan::CreateGrContext( const char* device_extensions[] = { VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, }; - GrVkExtensions vk_extensions; - vk_extensions.init(backend_context.fGetProc, backend_context.fInstance, + extensions.init(backend_context.fGetProc, backend_context.fInstance, backend_context.fPhysicalDevice, 0, nullptr, countof(device_extensions), device_extensions); - backend_context.fVkExtensions = &vk_extensions; */ GrContextOptions options = diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index 6044b74e3d1b8..8c8178777bf3e 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -9,6 +9,7 @@ #include "flutter/testing/test_vulkan_context.h" #include "include/gpu/GrDirectContext.h" +#include "include/gpu/vk/GrVkExtensions.h" #include "third_party/skia/include/core/SkSurface.h" #ifdef OS_MACOSX @@ -68,18 +69,20 @@ TestVulkanContext::TestVulkanContext() { return; } - GrVkBackendContext backend_context = { - .fInstance = application_->GetInstance(), - .fPhysicalDevice = device_->GetPhysicalDeviceHandle(), - .fDevice = device_->GetHandle(), - .fQueue = device_->GetQueueHandle(), - .fGraphicsQueueIndex = device_->GetGraphicsQueueIndex(), - .fMinAPIVersion = VK_MAKE_VERSION(1, 0, 0), - .fMaxAPIVersion = VK_MAKE_VERSION(1, 0, 0), - .fFeatures = skia_features, - .fGetProc = get_proc, - .fOwnsInstanceAndDevice = false, - }; + GrVkExtensions extensions; + + GrVkBackendContext backend_context = {}; + backend_context.fInstance = application_->GetInstance(); + backend_context.fPhysicalDevice = device_->GetPhysicalDeviceHandle(); + backend_context.fDevice = device_->GetHandle(); + backend_context.fQueue = device_->GetQueueHandle(); + backend_context.fGraphicsQueueIndex = device_->GetGraphicsQueueIndex(); + backend_context.fMinAPIVersion = VK_MAKE_VERSION(1, 0, 0); + backend_context.fMaxAPIVersion = VK_MAKE_VERSION(1, 0, 0); + backend_context.fFeatures = skia_features; + backend_context.fVkExtensions = &extensions; + backend_context.fGetProc = get_proc; + backend_context.fOwnsInstanceAndDevice = false; GrContextOptions options = MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kVulkan); From 07adc2d5f661c5d0bb45aa02388f905cc367230c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 30 Nov 2021 14:22:19 -0800 Subject: [PATCH 16/60] Heap alloc the test context and surface --- .../embedder/tests/embedder_config_builder.cc | 12 +++++------ .../tests/embedder_test_context_vulkan.cc | 13 ++++++------ .../tests/embedder_test_context_vulkan.h | 4 +++- testing/test_vulkan_surface.cc | 20 +++++++++++++------ testing/test_vulkan_surface.h | 8 ++++++-- 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 9a31fdf3ee486..eb56351a4ba7f 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -455,24 +455,24 @@ void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); vulkan_renderer_config_.instance = static_cast(context_) - .context_.application_->GetInstance(); + .context_->application_->GetInstance(); vulkan_renderer_config_.physical_device = static_cast(context_) - .context_.device_->GetPhysicalDeviceHandle(); + .context_->device_->GetPhysicalDeviceHandle(); vulkan_renderer_config_.device = static_cast(context_) - .context_.device_->GetHandle(); + .context_->device_->GetHandle(); vulkan_renderer_config_.queue_family_index = static_cast(context_) - .context_.device_->GetGraphicsQueueIndex(); + .context_->device_->GetGraphicsQueueIndex(); vulkan_renderer_config_.queue = static_cast(context_) - .context_.device_->GetQueueHandle(); + .context_->device_->GetQueueHandle(); vulkan_renderer_config_.get_instance_proc_address_callback = [](void* context, FlutterVulkanInstanceHandle instance, const char* name) -> void* { return reinterpret_cast(context) - ->context_.vk_->GetInstanceProcAddr( + ->context_->vk_->GetInstanceProcAddr( reinterpret_cast(instance), name); }; vulkan_renderer_config_.get_next_image_callback = diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc index 93ea21903f27f..6b373116d2f71 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -10,25 +10,26 @@ #include "flutter/fml/logging.h" // #include // "flutter/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h" - #include "flutter/vulkan/vulkan_device.h" #include "flutter/vulkan/vulkan_proc_table.h" +#include "testing/test_vulkan_context.h" +#include "testing/test_vulkan_surface.h" +#include "third_party/skia/include/core/SkSurface.h" namespace flutter { namespace testing { EmbedderTestContextVulkan::EmbedderTestContextVulkan(std::string assets_path) - : EmbedderTestContext(assets_path), context_() {} + : EmbedderTestContext(assets_path), + context_(std::make_unique()), + surface_() {} EmbedderTestContextVulkan::~EmbedderTestContextVulkan() {} void EmbedderTestContextVulkan::SetupSurface(SkISize surface_size) { FML_CHECK(surface_size_.isEmpty()); surface_size_ = surface_size; - - assert(false); // TODO(bdero) - // vulkan_surface_ = TestVulkanSurface::Create(*vulkan_context_, - // surface_size_); + surface_ = TestVulkanSurface::Create(*context_, surface_size_); } size_t EmbedderTestContextVulkan::GetSurfacePresentCount() const { diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.h b/shell/platform/embedder/tests/embedder_test_context_vulkan.h index 8effcbe1e7b5c..d5cfc71b3e4cd 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.h +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.h @@ -8,6 +8,7 @@ #include "flutter/shell/platform/embedder/tests/embedder_test_context.h" #include "flutter/testing/test_vulkan_context.h" #include "flutter/vulkan/vulkan_application.h" +#include "testing/test_vulkan_surface.h" namespace flutter { namespace testing { @@ -32,7 +33,8 @@ class EmbedderTestContextVulkan : public EmbedderTestContext { bool PresentImage(VkImage image); private: - TestVulkanContext context_; + std::unique_ptr context_; + std::unique_ptr surface_; SkISize surface_size_ = SkISize::MakeEmpty(); size_t present_count_ = 0; diff --git a/testing/test_vulkan_surface.cc b/testing/test_vulkan_surface.cc index 76d440638ceaf..3e403c89023fc 100644 --- a/testing/test_vulkan_surface.cc +++ b/testing/test_vulkan_surface.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "flutter/testing/test_vulkan_surface.h" +#include #include "flutter/fml/logging.h" #include "flutter/testing/test_vulkan_context.h" @@ -12,13 +13,16 @@ namespace flutter { namespace testing { -TestVulkanSurface::TestVulkanSurface(const TestVulkanContext& context, - const SkISize& surface_size) { +TestVulkanSurface::TestVulkanSurface() = default; + +std::unique_ptr TestVulkanSurface::Create( + const TestVulkanContext& context, + const SkISize& surface_size) { VkImage image = context.CreateImage(surface_size); if (!image) { FML_LOG(ERROR) << "Could not create VkImage."; - return; + return nullptr; } GrVkImageInfo image_info = { @@ -40,7 +44,9 @@ TestVulkanSurface::TestVulkanSurface(const TestVulkanContext& context, SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); - surface_ = SkSurface::MakeFromBackendTexture( + auto result = std::unique_ptr(new TestVulkanSurface()); + + result->surface_ = SkSurface::MakeFromBackendTexture( context.GetGrDirectContext().get(), // context backend_texture, // back-end texture kTopLeft_GrSurfaceOrigin, // surface origin @@ -52,11 +58,13 @@ TestVulkanSurface::TestVulkanSurface(const TestVulkanContext& context, nullptr // release context ); - if (!surface_) { + if (!result->surface_) { FML_LOG(ERROR) << "Could not wrap VkImage as an SkSurface Vulkan render texture."; - return; + return nullptr; } + + return result; } bool TestVulkanSurface::IsValid() const { diff --git a/testing/test_vulkan_surface.h b/testing/test_vulkan_surface.h index 380b5ba9ab5b4..3418c04ebda72 100644 --- a/testing/test_vulkan_surface.h +++ b/testing/test_vulkan_surface.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_TESTING_TEST_VULKAN_SURFACE_IMPL_H_ #define FLUTTER_TESTING_TEST_VULKAN_SURFACE_IMPL_H_ +#include #include "flutter/testing/test_vulkan_context.h" #include "third_party/skia/include/core/SkRefCnt.h" @@ -17,14 +18,17 @@ namespace testing { class TestVulkanSurface { public: - TestVulkanSurface(const TestVulkanContext& context, - const SkISize& surface_size); + static std::unique_ptr Create( + const TestVulkanContext& context, + const SkISize& surface_size); bool IsValid() const; sk_sp GetSurfaceSnapshot() const; private: + TestVulkanSurface(); + sk_sp surface_; }; From 58c4ad03da4a6460e2cfc5150f190c61877f1656 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 2 Dec 2021 01:24:50 -0800 Subject: [PATCH 17/60] Fix EmbedderSurfaceVulkan destruct crash --- .../platform/embedder/embedder_surface_vulkan.cc | 15 ++++++++------- shell/platform/embedder/embedder_surface_vulkan.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index 8078c5cb4a9e7..b4a299a65eddc 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -21,8 +21,9 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( VkQueue queue, VulkanDispatchTable vulkan_dispatch_table, std::shared_ptr external_view_embedder) - : vk_(vulkan_dispatch_table.get_instance_proc_address), - device_(vk_, + : vk_(fml::MakeRefCounted( + vulkan_dispatch_table.get_instance_proc_address)), + device_(*vk_, vulkan::VulkanHandle{physical_device}, vulkan::VulkanHandle{device}, queue_family_index, @@ -36,9 +37,9 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( return; } - vk_.SetupInstanceProcAddresses(vulkan::VulkanHandle{instance}); - vk_.SetupDeviceProcAddresses(vulkan::VulkanHandle{device}); - if (!vk_.IsValid()) { + vk_->SetupInstanceProcAddresses(vulkan::VulkanHandle{instance}); + vk_->SetupDeviceProcAddresses(vulkan::VulkanHandle{device}); + if (!vk_->IsValid()) { FML_LOG(ERROR) << "VulkanProcTable invalid."; return; } @@ -58,7 +59,7 @@ EmbedderSurfaceVulkan::~EmbedderSurfaceVulkan() = default; // |GPUSurfaceVulkanDelegate| const vulkan::VulkanProcTable& EmbedderSurfaceVulkan::vk() { - return vk_; + return *vk_; } // |GPUSurfaceVulkanDelegate| @@ -98,7 +99,7 @@ sk_sp EmbedderSurfaceVulkan::CreateGrContext( return nullptr; } - auto get_proc = vk_.CreateSkiaGetProc(); + auto get_proc = vk_->CreateSkiaGetProc(); if (get_proc == nullptr) { FML_LOG(ERROR) << "Failed to create Vulkan getProc for Skia."; return nullptr; diff --git a/shell/platform/embedder/embedder_surface_vulkan.h b/shell/platform/embedder/embedder_surface_vulkan.h index fe13db8f7692d..6bce55005d2a2 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.h +++ b/shell/platform/embedder/embedder_surface_vulkan.h @@ -49,7 +49,7 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface, private: bool valid_ = false; - vulkan::VulkanProcTable vk_; + fml::RefPtr vk_; vulkan::VulkanDevice device_; VulkanDispatchTable vulkan_dispatch_table_; std::shared_ptr external_view_embedder_; From 991655b7d5e9b78a840d14c36cefb82cd6fd6485 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 2 Dec 2021 01:26:28 -0800 Subject: [PATCH 18/60] Validate vulkan render config --- shell/platform/embedder/embedder.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 4f287f153e9f0..bc08816398b80 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -164,6 +164,26 @@ static bool IsMetalRendererConfigValid(const FlutterRendererConfig* config) { return device && command_queue && present && get_texture; } +static bool IsVulkanRendererConfigValid(const FlutterRendererConfig* config) { + if (config->type != kVulkan) { + return false; + } + + const FlutterVulkanRendererConfig* vulkan_config = &config->vulkan; + + if (!SAFE_EXISTS(vulkan_config, instance) || + !SAFE_EXISTS(vulkan_config, physical_device) || + !SAFE_EXISTS(vulkan_config, device) || + !SAFE_EXISTS(vulkan_config, queue) || + !SAFE_EXISTS(vulkan_config, get_instance_proc_address_callback) || + !SAFE_EXISTS(vulkan_config, get_next_image_callback) || + !SAFE_EXISTS(vulkan_config, present_image_callback)) { + return false; + } + + return true; +} + static bool IsRendererValid(const FlutterRendererConfig* config) { if (config == nullptr) { return false; @@ -176,6 +196,8 @@ static bool IsRendererValid(const FlutterRendererConfig* config) { return IsSoftwareRendererConfigValid(config); case kMetal: return IsMetalRendererConfigValid(config); + case kVulkan: + return IsVulkanRendererConfigValid(config); default: return false; } From da9ee48c522957969dd54c096cbff98a4864ded7 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 2 Dec 2021 01:54:39 -0800 Subject: [PATCH 19/60] Allocate image memory for test surface; parameterize a GL raster test --- .../embedder/tests/embedder_config_builder.cc | 19 +++++ .../embedder/tests/embedder_config_builder.h | 2 + shell/platform/embedder/tests/embedder_test.h | 5 ++ .../tests/embedder_test_context_vulkan.cc | 9 +-- .../embedder/tests/embedder_unittests_gl.cc | 13 +++- testing/BUILD.gn | 2 + testing/test_vulkan_context.cc | 70 +++++++++++++++++-- testing/test_vulkan_context.h | 3 +- testing/test_vulkan_image.cc | 22 ++++++ testing/test_vulkan_image.h | 37 ++++++++++ testing/test_vulkan_surface.cc | 17 +++-- testing/test_vulkan_surface.h | 5 +- 12 files changed, 184 insertions(+), 20 deletions(-) create mode 100644 testing/test_vulkan_image.cc create mode 100644 testing/test_vulkan_image.h diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index eb56351a4ba7f..8587fe3ec97e0 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -6,6 +6,7 @@ #include "flutter/runtime/dart_vm.h" #include "flutter/shell/platform/embedder/embedder.h" +#include "tests/embedder_test_context.h" #include "third_party/skia/include/core/SkBitmap.h" #ifdef SHELL_ENABLE_GL @@ -163,6 +164,24 @@ void EmbedderConfigBuilder::SetOpenGLPresentCallBack() { #endif } +void EmbedderConfigBuilder::SetRenderConfig(EmbedderTestContextType type, + SkISize surface_size) { + switch (type) { + case EmbedderTestContextType::kOpenGLContext: + SetOpenGLRendererConfig(surface_size); + break; + case EmbedderTestContextType::kMetalContext: + SetMetalRendererConfig(surface_size); + break; + case EmbedderTestContextType::kVulkanContext: + SetVulkanRendererConfig(surface_size); + break; + case EmbedderTestContextType::kSoftwareContext: + SetSoftwareRendererConfig(surface_size); + break; + } +} + void EmbedderConfigBuilder::SetOpenGLRendererConfig(SkISize surface_size) { #ifdef SHELL_ENABLE_GL renderer_config_.type = FlutterRendererType::kOpenGL; diff --git a/shell/platform/embedder/tests/embedder_config_builder.h b/shell/platform/embedder/tests/embedder_config_builder.h index 4cdf2a33d8b6e..c37589a3aae55 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.h +++ b/shell/platform/embedder/tests/embedder_config_builder.h @@ -45,6 +45,8 @@ class EmbedderConfigBuilder { FlutterProjectArgs& GetProjectArgs(); + void SetRenderConfig(EmbedderTestContextType type, SkISize surface_size); + void SetSoftwareRendererConfig(SkISize surface_size = SkISize::Make(1, 1)); void SetOpenGLRendererConfig(SkISize surface_size); diff --git a/shell/platform/embedder/tests/embedder_test.h b/shell/platform/embedder/tests/embedder_test.h index f00d802e0f23d..eb16637872872 100644 --- a/shell/platform/embedder/tests/embedder_test.h +++ b/shell/platform/embedder/tests/embedder_test.h @@ -12,6 +12,7 @@ #include "flutter/shell/platform/embedder/tests/embedder_test_context.h" #include "flutter/testing/testing.h" #include "flutter/testing/thread_test.h" +#include "gtest/gtest.h" namespace flutter { namespace testing { @@ -31,6 +32,10 @@ class EmbedderTest : public ThreadTest { FML_DISALLOW_COPY_AND_ASSIGN(EmbedderTest); }; +class EmbedderTestMultiBackend + : public EmbedderTest, + public ::testing::WithParamInterface {}; + } // namespace testing } // namespace flutter diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc index 6b373116d2f71..6b248d33e3c49 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -37,13 +37,14 @@ size_t EmbedderTestContextVulkan::GetSurfacePresentCount() const { } VkImage EmbedderTestContextVulkan::GetNextImage(const SkISize& size) { - assert(false); // TODO(bdero) - return nullptr; + return surface_->GetImage(); } bool EmbedderTestContextVulkan::PresentImage(VkImage image) { - assert(false); // TODO(bdero) - return false; + FireRootSurfacePresentCallbackIfPresent( + [&]() { return surface_->GetSurfaceSnapshot(); }); + present_count_++; + return true; } EmbedderTestContextType EmbedderTestContextVulkan::GetContextType() const { diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index ffa1272bb5ba3..240f8240ced97 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "tests/embedder_test_context.h" #define FML_USED_ON_EMBEDDER #include @@ -1235,13 +1236,13 @@ TEST_F(EmbedderTest, CanRenderSceneWithoutCustomCompositorWithTransformation) { "scene_without_custom_compositor_with_xform.png", rendered_scene)); } -TEST_F(EmbedderTest, CanRenderGradientWithoutCompositor) { - auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext); +TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositor) { + auto& context = GetEmbedderContext(GetParam()); EmbedderConfigBuilder builder(context); builder.SetDartEntrypoint("render_gradient"); - builder.SetOpenGLRendererConfig(SkISize::Make(800, 600)); + builder.SetRenderConfig(GetParam(), SkISize::Make(800, 600)); auto rendered_scene = context.GetNextSceneImage(); @@ -3688,5 +3689,11 @@ TEST_F(EmbedderTest, ExternalTextureGLRefreshedTooOften) { EXPECT_TRUE(resolve_called); } +INSTANTIATE_TEST_SUITE_P( + EmbedderTestGlVk, + EmbedderTestMultiBackend, + ::testing::Values(EmbedderTestContextType::kOpenGLContext, + EmbedderTestContextType::kVulkanContext)); + } // namespace testing } // namespace flutter diff --git a/testing/BUILD.gn b/testing/BUILD.gn index 394b9d74db3d0..3b47f5ac25d59 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn @@ -128,6 +128,8 @@ if (enable_unittests) { sources = [ "test_vulkan_context.cc", "test_vulkan_context.h", + "test_vulkan_image.cc", + "test_vulkan_image.h", "test_vulkan_surface.cc", "test_vulkan_surface.h", ] diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index 8c8178777bf3e..70cb88357e2ed 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -3,14 +3,16 @@ // found in the LICENSE file. #include +#include #include "flutter/fml/logging.h" #include "flutter/shell/common/context_options.h" #include "flutter/testing/test_vulkan_context.h" -#include "include/gpu/GrDirectContext.h" -#include "include/gpu/vk/GrVkExtensions.h" #include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/gpu/GrDirectContext.h" +#include "third_party/skia/include/gpu/vk/GrVkExtensions.h" +#include "vulkan/vulkan_core.h" #ifdef OS_MACOSX #define VULKAN_SO_PATH "libvk_swiftshader.dylib" @@ -90,9 +92,67 @@ TestVulkanContext::TestVulkanContext() { context_ = GrDirectContext::MakeVulkan(backend_context, options); } -VkImage TestVulkanContext::CreateImage(const SkISize& size) const { - assert(false); // TODO(bdero) - return nullptr; +std::optional TestVulkanContext::CreateImage( + const SkISize& size) const { + TestVulkanImage result; + + VkImageCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .imageType = VK_IMAGE_TYPE_2D, + .format = VK_FORMAT_R8G8B8A8_UNORM, + .extent = VkExtent3D{static_cast(size.width()), + static_cast(size.height()), 1}, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = nullptr, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + VkImage image; + if (VK_CALL_LOG_ERROR(VK_CALL_LOG_ERROR( + vk_->CreateImage(device_->GetHandle(), &info, nullptr, &image)))) { + return std::nullopt; + } + + result.image_ = vulkan::VulkanHandle( + image, [&vk = vk_, &device = device_](VkImage image) { + vk->DestroyImage(device->GetHandle(), image, nullptr); + }); + + VkMemoryRequirements mem_req; + vk_->GetImageMemoryRequirements(device_->GetHandle(), image, &mem_req); + VkMemoryAllocateInfo alloc_info{}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = mem_req.size; + alloc_info.memoryTypeIndex = static_cast(__builtin_ctz( + mem_req.memoryTypeBits & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)); + + VkDeviceMemory memory; + if (VK_CALL_LOG_ERROR(vk_->AllocateMemory(device_->GetHandle(), &alloc_info, + nullptr, &memory)) != VK_SUCCESS) { + return std::nullopt; + } + + result.memory_ = vulkan::VulkanHandle{ + memory, [&vk = vk_, &device = device_](VkDeviceMemory memory) { + vk->FreeMemory(device->GetHandle(), memory, nullptr); + }}; + + if (VK_CALL_LOG_ERROR(VK_CALL_LOG_ERROR(vk_->BindImageMemory( + device_->GetHandle(), result.image_, result.memory_, 0)))) { + return std::nullopt; + } + + return result; } sk_sp TestVulkanContext::GetGrDirectContext() const { diff --git a/testing/test_vulkan_context.h b/testing/test_vulkan_context.h index 8e4b4eb57f159..d828a7258e18a 100644 --- a/testing/test_vulkan_context.h +++ b/testing/test_vulkan_context.h @@ -7,6 +7,7 @@ #include "flutter/fml/macros.h" #include "flutter/fml/memory/ref_ptr.h" +#include "flutter/testing/test_vulkan_image.h" #include "flutter/vulkan/vulkan_application.h" #include "flutter/vulkan/vulkan_device.h" #include "flutter/vulkan/vulkan_proc_table.h" @@ -21,7 +22,7 @@ class TestVulkanContext { public: TestVulkanContext(); - VkImage CreateImage(const SkISize& size) const; + std::optional CreateImage(const SkISize& size) const; sk_sp GetGrDirectContext() const; diff --git a/testing/test_vulkan_image.cc b/testing/test_vulkan_image.cc new file mode 100644 index 0000000000000..f4bf01ac87923 --- /dev/null +++ b/testing/test_vulkan_image.cc @@ -0,0 +1,22 @@ +// 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. + +#include "flutter/testing/test_vulkan_image.h" + +namespace flutter { +namespace testing { + +TestVulkanImage::TestVulkanImage() = default; + +TestVulkanImage::TestVulkanImage(TestVulkanImage&& other) = default; +TestVulkanImage& TestVulkanImage::operator=(TestVulkanImage&& other) = default; + +TestVulkanImage::~TestVulkanImage() = default; + +VkImage TestVulkanImage::GetImage() { + return image_; +} + +} // namespace testing +} // namespace flutter diff --git a/testing/test_vulkan_image.h b/testing/test_vulkan_image.h new file mode 100644 index 0000000000000..33b497cfb0205 --- /dev/null +++ b/testing/test_vulkan_image.h @@ -0,0 +1,37 @@ +// 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. + +#include "flutter/fml/macros.h" +#include "flutter/vulkan/vulkan_handle.h" + +#include "third_party/skia/include/core/SkSize.h" + +namespace flutter { +namespace testing { + +class TestVulkanContext; + +/// Captures the lifetime of a test VkImage along with its bound memory. +class TestVulkanImage { + public: + TestVulkanImage(TestVulkanImage&& other); + TestVulkanImage& operator=(TestVulkanImage&& other); + + ~TestVulkanImage(); + + VkImage GetImage(); + + private: + TestVulkanImage(); + + vulkan::VulkanHandle image_; + vulkan::VulkanHandle memory_; + + FML_DISALLOW_COPY_AND_ASSIGN(TestVulkanImage); + + friend TestVulkanContext; +}; + +} // namespace testing +} // namespace flutter diff --git a/testing/test_vulkan_surface.cc b/testing/test_vulkan_surface.cc index 3e403c89023fc..6bca8ed44f599 100644 --- a/testing/test_vulkan_surface.cc +++ b/testing/test_vulkan_surface.cc @@ -13,20 +13,21 @@ namespace flutter { namespace testing { -TestVulkanSurface::TestVulkanSurface() = default; +TestVulkanSurface::TestVulkanSurface(TestVulkanImage&& image) + : image_(std::move(image)){}; std::unique_ptr TestVulkanSurface::Create( const TestVulkanContext& context, const SkISize& surface_size) { - VkImage image = context.CreateImage(surface_size); + auto image_result = context.CreateImage(surface_size); - if (!image) { + if (!image_result.has_value()) { FML_LOG(ERROR) << "Could not create VkImage."; return nullptr; } GrVkImageInfo image_info = { - .fImage = static_cast(image), + .fImage = image_result.value().GetImage(), .fImageTiling = VK_IMAGE_TILING_OPTIMAL, .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, .fFormat = VK_FORMAT_R8G8B8A8_UNORM, @@ -44,8 +45,8 @@ std::unique_ptr TestVulkanSurface::Create( SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); - auto result = std::unique_ptr(new TestVulkanSurface()); - + auto result = std::unique_ptr( + new TestVulkanSurface(std::move(image_result.value()))); result->surface_ = SkSurface::MakeFromBackendTexture( context.GetGrDirectContext().get(), // context backend_texture, // back-end texture @@ -101,5 +102,9 @@ sk_sp TestVulkanSurface::GetSurfaceSnapshot() const { return host_snapshot; } +VkImage TestVulkanSurface::GetImage() { + return image_.GetImage(); +} + } // namespace testing } // namespace flutter diff --git a/testing/test_vulkan_surface.h b/testing/test_vulkan_surface.h index 3418c04ebda72..4dce92fe725f8 100644 --- a/testing/test_vulkan_surface.h +++ b/testing/test_vulkan_surface.h @@ -26,9 +26,12 @@ class TestVulkanSurface { sk_sp GetSurfaceSnapshot() const; + VkImage GetImage(); + private: - TestVulkanSurface(); + explicit TestVulkanSurface(TestVulkanImage&& image); + TestVulkanImage image_; sk_sp surface_; }; From bec156f21e6b3ab4b3b2b39749dfd87b198071c6 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 8 Dec 2021 16:35:40 -0800 Subject: [PATCH 20/60] vk test image --- shell/platform/embedder/BUILD.gn | 1 + .../platform/embedder/fixtures/vk_gradient.png | Bin 0 -> 33551 bytes .../embedder/tests/embedder_unittests_gl.cc | 8 +++++--- .../embedder/tests/embedder_unittests_util.cc | 10 ++++++++++ .../embedder/tests/embedder_unittests_util.h | 3 +++ 5 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 shell/platform/embedder/fixtures/vk_gradient.png diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 28483d80965b0..e0ab72cd21dad 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -175,6 +175,7 @@ test_fixtures("fixtures") { "fixtures/dpr_noxform.png", "fixtures/dpr_xform.png", "fixtures/gradient.png", + "fixtures/vk_gradient.png", "fixtures/gradient_metal.png", "fixtures/external_texture_metal.png", "fixtures/gradient_xform.png", diff --git a/shell/platform/embedder/fixtures/vk_gradient.png b/shell/platform/embedder/fixtures/vk_gradient.png new file mode 100644 index 0000000000000000000000000000000000000000..27b69ecbb85c3378360309a32dc3bcc3bf7aa76f GIT binary patch literal 33551 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 UrPd1zz<>7Y9@0tLZF%K?023lP a, sk_sp b) { return normalized_a->equals(normalized_b.get()); } +std::string ImagePrefix(EmbedderTestContextType backend, + const std::string& name) { + switch (backend) { + case EmbedderTestContextType::kVulkanContext: + return "vk_" + name; + default: + return name; + } +} + bool WriteImageToDisk(const fml::UniqueFD& directory, const std::string& name, sk_sp image) { diff --git a/shell/platform/embedder/tests/embedder_unittests_util.h b/shell/platform/embedder/tests/embedder_unittests_util.h index 35944cb13adc8..c07de974b071f 100644 --- a/shell/platform/embedder/tests/embedder_unittests_util.h +++ b/shell/platform/embedder/tests/embedder_unittests_util.h @@ -26,6 +26,9 @@ sk_sp CreateRenderSurface(const FlutterLayer& layer, bool RasterImagesAreSame(sk_sp a, sk_sp b); +std::string ImagePrefix(EmbedderTestContextType backend, + const std::string& name); + bool WriteImageToDisk(const fml::UniqueFD& directory, const std::string& name, sk_sp image); From 37d698d74a5c99200b521ce09762ed0a7d24897e Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 8 Dec 2021 18:34:18 -0800 Subject: [PATCH 21/60] Fix vk gradient --- .../embedder/fixtures/vk_gradient.png | Bin 33551 -> 33546 bytes .../embedder/tests/embedder_unittests_gl.cc | 10 ++++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/shell/platform/embedder/fixtures/vk_gradient.png b/shell/platform/embedder/fixtures/vk_gradient.png index 27b69ecbb85c3378360309a32dc3bcc3bf7aa76f..b00a8baf8d2e5301bd978fc12d212e15ab02ed6c 100644 GIT binary patch delta 10677 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 diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 819e54ad8de12..1bd284ccedb53 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -1263,8 +1263,9 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositor) { rendered_scene)); } -TEST_F(EmbedderTest, CanRenderGradientWithoutCompositorWithXform) { - auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext); +TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositorWithXform) { + EmbedderTestContextType backend = GetParam(); + auto& context = GetEmbedderContext(backend); const auto root_surface_transformation = SkMatrix().preTranslate(0, 800).preRotate(-90, 0, 0); @@ -1276,7 +1277,7 @@ TEST_F(EmbedderTest, CanRenderGradientWithoutCompositorWithXform) { const auto surface_size = SkISize::Make(600, 800); builder.SetDartEntrypoint("render_gradient"); - builder.SetOpenGLRendererConfig(surface_size); + builder.SetRenderConfig(backend, surface_size); auto rendered_scene = context.GetNextSceneImage(); @@ -1293,7 +1294,8 @@ TEST_F(EmbedderTest, CanRenderGradientWithoutCompositorWithXform) { ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); - ASSERT_TRUE(ImageMatchesFixture("gradient_xform.png", rendered_scene)); + ASSERT_TRUE(ImageMatchesFixture(ImagePrefix(backend, "gradient.png"), + rendered_scene)); } TEST_F(EmbedderTest, CanRenderGradientWithCompositor) { From 27661720b716eba6999d34713c0648872be3ce2c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 8 Dec 2021 19:35:03 -0800 Subject: [PATCH 22/60] Get render target from target --- .../embedder_test_backingstore_producer.h | 1 + .../embedder/tests/embedder_unittests_util.cc | 22 ++++++++++++++++++- .../embedder/tests/embedder_unittests_util.h | 5 ++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h index f993891e44414..68ada75af6eda 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h @@ -24,6 +24,7 @@ class EmbedderTestBackingStoreProducer { kOpenGLFramebuffer, kOpenGLTexture, kMetalTexture, + kVulkanImage, }; EmbedderTestBackingStoreProducer(sk_sp context, diff --git a/shell/platform/embedder/tests/embedder_unittests_util.cc b/shell/platform/embedder/tests/embedder_unittests_util.cc index 2d194b1634837..09c2fa2ee3256 100644 --- a/shell/platform/embedder/tests/embedder_unittests_util.cc +++ b/shell/platform/embedder/tests/embedder_unittests_util.cc @@ -70,7 +70,7 @@ bool RasterImagesAreSame(sk_sp a, sk_sp b) { } std::string ImagePrefix(EmbedderTestContextType backend, - const std::string& name) { + const std::string& name) { switch (backend) { case EmbedderTestContextType::kVulkanContext: return "vk_" + name; @@ -79,6 +79,26 @@ std::string ImagePrefix(EmbedderTestContextType backend, } } +EmbedderTestBackingStoreProducer::RenderTargetType GetTargetFromBackend( + EmbedderTestContextType backend, + bool opengl_framebuffer) { + switch (backend) { + case EmbedderTestContextType::kVulkanContext: + return EmbedderTestBackingStoreProducer::RenderTargetType::kVulkanImage; + case EmbedderTestContextType::kOpenGLContext: + if (opengl_framebuffer) { + return EmbedderTestBackingStoreProducer::RenderTargetType:: + kOpenGLFramebuffer; + } + return EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLTexture; + case EmbedderTestContextType::kMetalContext: + return EmbedderTestBackingStoreProducer::RenderTargetType::kMetalTexture; + case EmbedderTestContextType::kSoftwareContext: + return EmbedderTestBackingStoreProducer::RenderTargetType:: + kSoftwareBuffer; + } +} + bool WriteImageToDisk(const fml::UniqueFD& directory, const std::string& name, sk_sp image) { diff --git a/shell/platform/embedder/tests/embedder_unittests_util.h b/shell/platform/embedder/tests/embedder_unittests_util.h index c07de974b071f..c2fd9d3b1637f 100644 --- a/shell/platform/embedder/tests/embedder_unittests_util.h +++ b/shell/platform/embedder/tests/embedder_unittests_util.h @@ -27,7 +27,10 @@ sk_sp CreateRenderSurface(const FlutterLayer& layer, bool RasterImagesAreSame(sk_sp a, sk_sp b); std::string ImagePrefix(EmbedderTestContextType backend, - const std::string& name); + const std::string& name); + +EmbedderTestBackingStoreProducer::RenderTargetType GetTargetFromBackend( + EmbedderTestContextType backend, bool opengl_framebuffer); bool WriteImageToDisk(const fml::UniqueFD& directory, const std::string& name, From 9afe4e290b2ba1494b5a56e02326ada9ceab9129 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 8 Dec 2021 20:40:26 -0800 Subject: [PATCH 23/60] Compositor gradient test --- .../embedder/tests/embedder_config_builder.cc | 2 +- .../embedder/tests/embedder_config_builder.h | 2 +- .../embedder/tests/embedder_unittests_gl.cc | 17 +++++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 8587fe3ec97e0..173a2adf807ac 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -164,7 +164,7 @@ void EmbedderConfigBuilder::SetOpenGLPresentCallBack() { #endif } -void EmbedderConfigBuilder::SetRenderConfig(EmbedderTestContextType type, +void EmbedderConfigBuilder::SetRendererConfig(EmbedderTestContextType type, SkISize surface_size) { switch (type) { case EmbedderTestContextType::kOpenGLContext: diff --git a/shell/platform/embedder/tests/embedder_config_builder.h b/shell/platform/embedder/tests/embedder_config_builder.h index c37589a3aae55..73256a36b3e01 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.h +++ b/shell/platform/embedder/tests/embedder_config_builder.h @@ -45,7 +45,7 @@ class EmbedderConfigBuilder { FlutterProjectArgs& GetProjectArgs(); - void SetRenderConfig(EmbedderTestContextType type, SkISize surface_size); + void SetRendererConfig(EmbedderTestContextType type, SkISize surface_size); void SetSoftwareRendererConfig(SkISize surface_size = SkISize::Make(1, 1)); diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 1bd284ccedb53..6b89e01f5c356 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -1243,7 +1243,7 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositor) { EmbedderConfigBuilder builder(context); builder.SetDartEntrypoint("render_gradient"); - builder.SetRenderConfig(backend, SkISize::Make(800, 600)); + builder.SetRendererConfig(backend, SkISize::Make(800, 600)); auto rendered_scene = context.GetNextSceneImage(); @@ -1277,7 +1277,7 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositorWithXform) { const auto surface_size = SkISize::Make(600, 800); builder.SetDartEntrypoint("render_gradient"); - builder.SetRenderConfig(backend, surface_size); + builder.SetRendererConfig(backend, surface_size); auto rendered_scene = context.GetNextSceneImage(); @@ -1298,16 +1298,16 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositorWithXform) { rendered_scene)); } -TEST_F(EmbedderTest, CanRenderGradientWithCompositor) { - auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext); +TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithCompositor) { + EmbedderTestContextType backend = GetParam(); + auto& context = GetEmbedderContext(backend); EmbedderConfigBuilder builder(context); builder.SetDartEntrypoint("render_gradient"); - builder.SetOpenGLRendererConfig(SkISize::Make(800, 600)); + builder.SetRendererConfig(backend, SkISize::Make(800, 600)); builder.SetCompositor(); - builder.SetRenderTargetType( - EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLFramebuffer); + builder.SetRenderTargetType(GetTargetFromBackend(backend, true)); auto rendered_scene = context.GetNextSceneImage(); @@ -1323,7 +1323,8 @@ TEST_F(EmbedderTest, CanRenderGradientWithCompositor) { ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); - ASSERT_TRUE(ImageMatchesFixture("gradient.png", rendered_scene)); + ASSERT_TRUE(ImageMatchesFixture(ImagePrefix(backend, "gradient.png"), + rendered_scene)); } TEST_F(EmbedderTest, CanRenderGradientWithCompositorWithXform) { From 33941fc742d672baf35bcb4405a072181e97c96c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 8 Dec 2021 22:03:01 -0800 Subject: [PATCH 24/60] Add test harness compositor (never finishes frame render for some reason) --- shell/platform/embedder/BUILD.gn | 2 + .../embedder_test_backingstore_producer.cc | 56 +++++++++ .../embedder_test_backingstore_producer.h | 3 + .../tests/embedder_test_compositor_vulkan.cc | 109 ++++++++++++++++++ .../tests/embedder_test_compositor_vulkan.h | 32 +++++ .../tests/embedder_test_context_vulkan.cc | 17 ++- 6 files changed, 209 insertions(+), 10 deletions(-) create mode 100644 shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc create mode 100644 shell/platform/embedder/tests/embedder_test_compositor_vulkan.h diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index e0ab72cd21dad..c32e465eebd1b 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -259,6 +259,8 @@ if (enable_unittests) { if (test_enable_vulkan) { sources += [ + "tests/embedder_test_compositor_vulkan.cc", + "tests/embedder_test_compositor_vulkan.h", "tests/embedder_test_context_vulkan.cc", "tests/embedder_test_context_vulkan.h", ] diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc index 6d0c6b9d254d5..b2e715f47c4b4 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc @@ -43,6 +43,10 @@ bool EmbedderTestBackingStoreProducer::Create( #ifdef SHELL_ENABLE_METAL case RenderTargetType::kMetalTexture: return CreateMTLTexture(config, renderer_out); +#endif +#ifdef SHELL_ENABLE_VULKAN + case RenderTargetType::kVulkanImage: + return CreateVulkanImage(config, renderer_out); #endif default: return false; @@ -229,5 +233,57 @@ bool EmbedderTestBackingStoreProducer::CreateMTLTexture( #endif } +bool EmbedderTestBackingStoreProducer::CreateVulkanImage( + const FlutterBackingStoreConfig* config, + FlutterBackingStore* backing_store_out) { +#ifdef SHELL_ENABLE_VULKAN + const auto image_info = + SkImageInfo::MakeN32Premul(config->size.width, config->size.height); + + auto surface = SkSurface::MakeRenderTarget( + context_.get(), // context + SkBudgeted::kNo, // budgeted + image_info, // image info + 1, // sample count + kBottomLeft_GrSurfaceOrigin, // surface origin + nullptr, // surface properties + false // mipmaps + ); + + if (!surface) { + FML_LOG(ERROR) << "Could not create render target for compositor layer."; + return false; + } + + GrBackendRenderTarget render_target = surface->getBackendRenderTarget( + SkSurface::BackendHandleAccess::kDiscardWrite_BackendHandleAccess); + + if (!render_target.isValid()) { + FML_LOG(ERROR) << "Backend render target was invalid."; + return false; + } + + GrVkImageInfo vkimage_info = {}; + if (!render_target.getVkImageInfo(&vkimage_info)) { + FML_LOG(ERROR) << "Could not access backend framebuffer info."; + return false; + } + + backing_store_out->type = kFlutterBackingStoreTypeVulkan; + backing_store_out->user_data = surface.get(); + backing_store_out->vulkan.user_data = surface.get(); + backing_store_out->vulkan.image.image = vkimage_info.fImage; + backing_store_out->vulkan.destruction_callback = [](void* user_data) { + reinterpret_cast(user_data)->unref(); + }; + // The balancing unref is in the destruction callback. + surface->ref(); + + return true; +#else + return false; +#endif +} + } // namespace testing } // namespace flutter diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h index 68ada75af6eda..849671781c3b8 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h @@ -47,6 +47,9 @@ class EmbedderTestBackingStoreProducer { bool CreateMTLTexture(const FlutterBackingStoreConfig* config, FlutterBackingStore* renderer_out); + bool CreateVulkanImage(const FlutterBackingStoreConfig* config, + FlutterBackingStore* renderer_out); + sk_sp context_; RenderTargetType type_; diff --git a/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc b/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc new file mode 100644 index 0000000000000..e180955416380 --- /dev/null +++ b/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc @@ -0,0 +1,109 @@ +// 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. + +#include "flutter/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h" + +#include "flutter/fml/logging.h" +#include "flutter/shell/platform/embedder/tests/embedder_assertions.h" +#include "third_party/skia/include/core/SkSurface.h" + +namespace flutter { +namespace testing { + +EmbedderTestCompositorVulkan::EmbedderTestCompositorVulkan( + SkISize surface_size, + sk_sp context) + : EmbedderTestCompositor(surface_size, context) {} + +EmbedderTestCompositorVulkan::~EmbedderTestCompositorVulkan() = default; + +bool EmbedderTestCompositorVulkan::UpdateOffscrenComposition( + const FlutterLayer** layers, + size_t layers_count) { + last_composition_ = nullptr; + + const auto image_info = SkImageInfo::MakeN32Premul(surface_size_); + + auto surface = + SkSurface::MakeRenderTarget(context_.get(), // context + SkBudgeted::kNo, // budgeted + image_info, // image info + 1, // sample count + kTopLeft_GrSurfaceOrigin, // surface origin + nullptr, // surface properties + false // create mipmaps + ); + + if (!surface) { + FML_LOG(ERROR) << "Could not update the off-screen composition."; + return false; + } + + auto canvas = surface->getCanvas(); + + // This has to be transparent because we are going to be compositing this + // sub-hierarchy onto the on-screen surface. + canvas->clear(SK_ColorTRANSPARENT); + + for (size_t i = 0; i < layers_count; ++i) { + const auto* layer = layers[i]; + + sk_sp platform_rendered_contents; + + sk_sp layer_image; + SkIPoint canvas_offset = SkIPoint::Make(0, 0); + + switch (layer->type) { + case kFlutterLayerContentTypeBackingStore: + layer_image = + reinterpret_cast(layer->backing_store->user_data) + ->makeImageSnapshot(); + break; + case kFlutterLayerContentTypePlatformView: + layer_image = + platform_view_renderer_callback_ + ? platform_view_renderer_callback_(*layer, context_.get()) + : nullptr; + canvas_offset = SkIPoint::Make(layer->offset.x, layer->offset.y); + break; + }; + + // If the layer is not a platform view but the engine did not specify an + // image for the backing store, it is an error. + if (!layer_image && layer->type != kFlutterLayerContentTypePlatformView) { + FML_LOG(ERROR) << "Could not snapshot layer in test compositor: " + << *layer; + return false; + } + + // The test could have just specified no contents to be rendered in place of + // a platform view. This is not an error. + if (layer_image) { + // The image rendered by Flutter already has the correct offset and + // transformation applied. The layers offset is meant for the platform. + canvas->drawImage(layer_image.get(), canvas_offset.x(), + canvas_offset.y()); + } + } + + last_composition_ = surface->makeImageSnapshot(); + + if (!last_composition_) { + FML_LOG(ERROR) << "Could not update the contents of the sub-composition."; + return false; + } + + if (next_scene_callback_) { + auto last_composition_snapshot = last_composition_->makeRasterImage(); + FML_CHECK(last_composition_snapshot); + auto callback = next_scene_callback_; + next_scene_callback_ = nullptr; + callback(std::move(last_composition_snapshot)); + } + + return true; +} + +} // namespace testing +} // namespace flutter diff --git a/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h b/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h new file mode 100644 index 0000000000000..0cc9e2e13dad0 --- /dev/null +++ b/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h @@ -0,0 +1,32 @@ +// 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. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_TEST_COMPOSITOR_VULKAN_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_TEST_COMPOSITOR_VULKAN_H_ + +#include "flutter/fml/macros.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/embedder/tests/embedder_test_compositor.h" + +namespace flutter { +namespace testing { + +class EmbedderTestCompositorVulkan : public EmbedderTestCompositor { + public: + EmbedderTestCompositorVulkan(SkISize surface_size, + sk_sp context); + + ~EmbedderTestCompositorVulkan() override; + + private: + bool UpdateOffscrenComposition(const FlutterLayer** layers, + size_t layers_count) override; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderTestCompositorVulkan); +}; + +} // namespace testing +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_TEST_COMPOSITOR_VULKAN_H_ diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc index 6b248d33e3c49..2e2a0abeca42b 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -8,12 +8,11 @@ #include "embedder.h" #include "flutter/fml/logging.h" -// #include -// "flutter/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h" +#include "flutter/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h" +#include "flutter/testing/test_vulkan_context.h" +#include "flutter/testing/test_vulkan_surface.h" #include "flutter/vulkan/vulkan_device.h" #include "flutter/vulkan/vulkan_proc_table.h" -#include "testing/test_vulkan_context.h" -#include "testing/test_vulkan_surface.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter { @@ -53,12 +52,10 @@ EmbedderTestContextType EmbedderTestContextVulkan::GetContextType() const { void EmbedderTestContextVulkan::SetupCompositor() { FML_CHECK(!compositor_) << "Already set up a compositor in this context."; - - assert(false); // TODO(bdero) - // FML_CHECK(vulkan_surface_) - // << "Set up the Vulkan surface before setting up a compositor."; - // compositor_ = std::make_unique( - // surface_size_, vulkan_surface_->GetGrContext()); + FML_CHECK(surface_) + << "Set up the Vulkan surface before setting up a compositor."; + compositor_ = std::make_unique( + surface_size_, context_->GetGrDirectContext()); } } // namespace testing From e26ba4746cbf34c6c4721ac681c59b7335d86f42 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 9 Dec 2021 00:04:10 -0800 Subject: [PATCH 25/60] Extensions --- testing/test_vulkan_context.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index 70cb88357e2ed..4d424b7c10270 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -36,8 +36,10 @@ TestVulkanContext::TestVulkanContext() { return; } - application_ = std::unique_ptr( - new vulkan::VulkanApplication(*vk_, "Flutter Unittests", {})); + application_ = + std::unique_ptr(new vulkan::VulkanApplication( + *vk_, "Flutter Unittests", {}, VK_MAKE_VERSION(1, 0, 0), + VK_MAKE_VERSION(1, 0, 0), true)); if (!application_->IsValid()) { FML_DLOG(ERROR) << "Failed to initialize basic Vulkan state."; return; From 4b28c39a1e66318bc98aa12e70b28476378ca815 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 9 Dec 2021 00:06:15 -0800 Subject: [PATCH 26/60] Format --- shell/platform/embedder/tests/embedder_config_builder.cc | 2 +- .../embedder/tests/embedder_test_backingstore_producer.h | 2 +- .../platform/embedder/tests/embedder_test_compositor_vulkan.h | 2 +- shell/platform/embedder/tests/embedder_unittests_util.h | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 173a2adf807ac..eba3111ff6e0d 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -165,7 +165,7 @@ void EmbedderConfigBuilder::SetOpenGLPresentCallBack() { } void EmbedderConfigBuilder::SetRendererConfig(EmbedderTestContextType type, - SkISize surface_size) { + SkISize surface_size) { switch (type) { case EmbedderTestContextType::kOpenGLContext: SetOpenGLRendererConfig(surface_size); diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h index 849671781c3b8..86d8e46870b45 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h @@ -48,7 +48,7 @@ class EmbedderTestBackingStoreProducer { FlutterBackingStore* renderer_out); bool CreateVulkanImage(const FlutterBackingStoreConfig* config, - FlutterBackingStore* renderer_out); + FlutterBackingStore* renderer_out); sk_sp context_; RenderTargetType type_; diff --git a/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h b/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h index 0cc9e2e13dad0..608bda52ec858 100644 --- a/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h +++ b/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h @@ -15,7 +15,7 @@ namespace testing { class EmbedderTestCompositorVulkan : public EmbedderTestCompositor { public: EmbedderTestCompositorVulkan(SkISize surface_size, - sk_sp context); + sk_sp context); ~EmbedderTestCompositorVulkan() override; diff --git a/shell/platform/embedder/tests/embedder_unittests_util.h b/shell/platform/embedder/tests/embedder_unittests_util.h index c2fd9d3b1637f..4fa04ad3e57b0 100644 --- a/shell/platform/embedder/tests/embedder_unittests_util.h +++ b/shell/platform/embedder/tests/embedder_unittests_util.h @@ -30,7 +30,8 @@ std::string ImagePrefix(EmbedderTestContextType backend, const std::string& name); EmbedderTestBackingStoreProducer::RenderTargetType GetTargetFromBackend( - EmbedderTestContextType backend, bool opengl_framebuffer); + EmbedderTestContextType backend, + bool opengl_framebuffer); bool WriteImageToDisk(const fml::UniqueFD& directory, const std::string& name, From ff68811a102501532c960e290e8334f54437d735 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 13 Dec 2021 16:54:01 -0800 Subject: [PATCH 27/60] Licenses --- ci/licenses_golden/licenses_flutter | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 608207369dff5..95efaddf54bc9 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1389,6 +1389,7 @@ FILE: ../../../flutter/shell/platform/embedder/fixtures/scene_without_custom_com FILE: ../../../flutter/shell/platform/embedder/fixtures/snapshot_large_scene.png FILE: ../../../flutter/shell/platform/embedder/fixtures/verifyb143464703.png FILE: ../../../flutter/shell/platform/embedder/fixtures/verifyb143464703_soft_noxform.png +FILE: ../../../flutter/shell/platform/embedder/fixtures/vk_gradient.png FILE: ../../../flutter/shell/platform/embedder/platform_view_embedder.cc FILE: ../../../flutter/shell/platform/embedder/platform_view_embedder.h FILE: ../../../flutter/shell/platform/embedder/test_utils/key_codes.h From 39b23b952ea777783b3e00a31c3b50ae4ac93c20 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 13 Dec 2021 17:05:17 -0800 Subject: [PATCH 28/60] Don't test root layer xform in vulkan (not supported in the API) --- shell/platform/embedder/tests/embedder_unittests_gl.cc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 6b89e01f5c356..ba84f95c0cfc2 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -1263,9 +1263,8 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositor) { rendered_scene)); } -TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositorWithXform) { - EmbedderTestContextType backend = GetParam(); - auto& context = GetEmbedderContext(backend); +TEST_F(EmbedderTest, CanRenderGradientWithoutCompositorWithXform) { + auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext); const auto root_surface_transformation = SkMatrix().preTranslate(0, 800).preRotate(-90, 0, 0); @@ -1277,7 +1276,7 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositorWithXform) { const auto surface_size = SkISize::Make(600, 800); builder.SetDartEntrypoint("render_gradient"); - builder.SetRendererConfig(backend, surface_size); + builder.SetOpenGLRendererConfig(surface_size); auto rendered_scene = context.GetNextSceneImage(); @@ -1294,8 +1293,7 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositorWithXform) { ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); - ASSERT_TRUE(ImageMatchesFixture(ImagePrefix(backend, "gradient.png"), - rendered_scene)); + ASSERT_TRUE(ImageMatchesFixture("gradient_xform.png", rendered_scene)); } TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithCompositor) { From 2831cba607f9cac5db8582058cb8ea5bcf44e74d Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 14 Dec 2021 04:02:12 -0800 Subject: [PATCH 29/60] Make TestVulkanContext destruct after the compositor, create VkImages and wrap them in the test harness instead of using Skia to generate render targets (they were silently non-writable for some reason), parameterize non-root compositor test --- .../embedder/tests/embedder_config_builder.cc | 12 ++-- .../embedder_test_backingstore_producer.cc | 71 +++++++++++-------- .../embedder_test_backingstore_producer.h | 8 +++ .../tests/embedder_test_compositor_vulkan.cc | 2 +- .../embedder/tests/embedder_test_context.h | 6 ++ .../tests/embedder_test_context_vulkan.cc | 11 ++- .../tests/embedder_test_context_vulkan.h | 2 +- .../embedder/tests/embedder_unittests_gl.cc | 22 +++--- .../embedder/tests/embedder_unittests_util.cc | 26 +++++++ .../embedder/tests/embedder_unittests_util.h | 5 +- 10 files changed, 109 insertions(+), 56 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index eba3111ff6e0d..07e251391992d 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -474,24 +474,24 @@ void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); vulkan_renderer_config_.instance = static_cast(context_) - .context_->application_->GetInstance(); + .vulkan_context_->application_->GetInstance(); vulkan_renderer_config_.physical_device = static_cast(context_) - .context_->device_->GetPhysicalDeviceHandle(); + .vulkan_context_->device_->GetPhysicalDeviceHandle(); vulkan_renderer_config_.device = static_cast(context_) - .context_->device_->GetHandle(); + .vulkan_context_->device_->GetHandle(); vulkan_renderer_config_.queue_family_index = static_cast(context_) - .context_->device_->GetGraphicsQueueIndex(); + .vulkan_context_->device_->GetGraphicsQueueIndex(); vulkan_renderer_config_.queue = static_cast(context_) - .context_->device_->GetQueueHandle(); + .vulkan_context_->device_->GetQueueHandle(); vulkan_renderer_config_.get_instance_proc_address_callback = [](void* context, FlutterVulkanInstanceHandle instance, const char* name) -> void* { return reinterpret_cast(context) - ->context_->vk_->GetInstanceProcAddr( + ->vulkan_context_->vk_->GetInstanceProcAddr( reinterpret_cast(instance), name); }; vulkan_renderer_config_.get_next_image_callback = diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc index b2e715f47c4b4..63e775aebfb5a 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc @@ -5,8 +5,8 @@ #include "flutter/shell/platform/embedder/tests/embedder_test_backingstore_producer.h" #include "flutter/fml/logging.h" -#include "include/core/SkImageInfo.h" -#include "include/core/SkSize.h" +#include "third_party/skia/include/core/SkImageInfo.h" +#include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkSurface.h" #include @@ -23,6 +23,10 @@ EmbedderTestBackingStoreProducer::EmbedderTestBackingStoreProducer( , test_metal_context_(std::make_unique()) #endif +#ifdef SHELL_ENABLE_VULKAN + , + test_vulkan_context_(std::make_unique()) +#endif { } @@ -237,42 +241,51 @@ bool EmbedderTestBackingStoreProducer::CreateVulkanImage( const FlutterBackingStoreConfig* config, FlutterBackingStore* backing_store_out) { #ifdef SHELL_ENABLE_VULKAN - const auto image_info = - SkImageInfo::MakeN32Premul(config->size.width, config->size.height); - - auto surface = SkSurface::MakeRenderTarget( - context_.get(), // context - SkBudgeted::kNo, // budgeted - image_info, // image info - 1, // sample count - kBottomLeft_GrSurfaceOrigin, // surface origin - nullptr, // surface properties - false // mipmaps - ); + auto surface_size = SkISize::Make(config->size.width, config->size.height); + TestVulkanImage* test_image = new TestVulkanImage( + std::move(test_vulkan_context_->CreateImage(surface_size).value())); + + GrVkImageInfo image_info = { + .fImage = test_image->GetImage(), + .fImageTiling = VK_IMAGE_TILING_OPTIMAL, + .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .fFormat = VK_FORMAT_R8G8B8A8_UNORM, + .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT, + .fSampleCount = 1, + .fLevelCount = 1, + }; + GrBackendTexture backend_texture(surface_size.width(), surface_size.height(), + image_info); - if (!surface) { - FML_LOG(ERROR) << "Could not create render target for compositor layer."; - return false; - } + SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); - GrBackendRenderTarget render_target = surface->getBackendRenderTarget( - SkSurface::BackendHandleAccess::kDiscardWrite_BackendHandleAccess); + SkSurface::TextureReleaseProc release_vktexture = [](void* user_data) { + delete reinterpret_cast(user_data); + }; - if (!render_target.isValid()) { - FML_LOG(ERROR) << "Backend render target was invalid."; - return false; - } + sk_sp surface = SkSurface::MakeFromBackendTexture( + context_.get(), // context + backend_texture, // back-end texture + kTopLeft_GrSurfaceOrigin, // surface origin + 1, // sample count + kRGBA_8888_SkColorType, // color type + SkColorSpace::MakeSRGB(), // color space + &surface_properties, // surface properties + release_vktexture, // texture release proc + test_image // release context + ); - GrVkImageInfo vkimage_info = {}; - if (!render_target.getVkImageInfo(&vkimage_info)) { - FML_LOG(ERROR) << "Could not access backend framebuffer info."; + if (!surface) { + FML_LOG(ERROR) << "Could not create Skia surface from Vulkan image."; return false; } - backing_store_out->type = kFlutterBackingStoreTypeVulkan; backing_store_out->user_data = surface.get(); backing_store_out->vulkan.user_data = surface.get(); - backing_store_out->vulkan.image.image = vkimage_info.fImage; + backing_store_out->vulkan.image.image = image_info.fImage; backing_store_out->vulkan.destruction_callback = [](void* user_data) { reinterpret_cast(user_data)->unref(); }; diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h index 86d8e46870b45..f1ba8469f38af 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h @@ -14,6 +14,10 @@ #include "flutter/testing/test_metal_context.h" #endif +#ifdef SHELL_ENABLE_VULKAN +#include "flutter/testing/test_vulkan_context.h" +#endif + namespace flutter { namespace testing { @@ -57,6 +61,10 @@ class EmbedderTestBackingStoreProducer { std::unique_ptr test_metal_context_; #endif +#ifdef SHELL_ENABLE_VULKAN + std::unique_ptr test_vulkan_context_; +#endif + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderTestBackingStoreProducer); }; diff --git a/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc b/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc index e180955416380..f5fc6884e4766 100644 --- a/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc @@ -25,7 +25,7 @@ bool EmbedderTestCompositorVulkan::UpdateOffscrenComposition( const auto image_info = SkImageInfo::MakeN32Premul(surface_size_); - auto surface = + sk_sp surface = SkSurface::MakeRenderTarget(context_.get(), // context SkBudgeted::kNo, // budgeted image_info, // image info diff --git a/shell/platform/embedder/tests/embedder_test_context.h b/shell/platform/embedder/tests/embedder_test_context.h index 74d2cd064b7b5..907fa332435a3 100644 --- a/shell/platform/embedder/tests/embedder_test_context.h +++ b/shell/platform/embedder/tests/embedder_test_context.h @@ -106,6 +106,12 @@ class EmbedderTestContext { using NextSceneCallback = std::function image)>; + #ifdef SHELL_ENABLE_VULKAN + // The TestVulkanContext destructor must be called _after_ the compositor is + // freed. + std::unique_ptr vulkan_context_ = nullptr; + #endif + std::string assets_path_; ELFAOTSymbols aot_symbols_; std::unique_ptr vm_snapshot_data_; diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc index 2e2a0abeca42b..a92a6cc88d8e1 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -6,7 +6,6 @@ #include -#include "embedder.h" #include "flutter/fml/logging.h" #include "flutter/shell/platform/embedder/tests/embedder_test_compositor_vulkan.h" #include "flutter/testing/test_vulkan_context.h" @@ -19,16 +18,16 @@ namespace flutter { namespace testing { EmbedderTestContextVulkan::EmbedderTestContextVulkan(std::string assets_path) - : EmbedderTestContext(assets_path), - context_(std::make_unique()), - surface_() {} + : EmbedderTestContext(assets_path), surface_() { + vulkan_context_ = std::make_unique(); +} EmbedderTestContextVulkan::~EmbedderTestContextVulkan() {} void EmbedderTestContextVulkan::SetupSurface(SkISize surface_size) { FML_CHECK(surface_size_.isEmpty()); surface_size_ = surface_size; - surface_ = TestVulkanSurface::Create(*context_, surface_size_); + surface_ = TestVulkanSurface::Create(*vulkan_context_, surface_size_); } size_t EmbedderTestContextVulkan::GetSurfacePresentCount() const { @@ -55,7 +54,7 @@ void EmbedderTestContextVulkan::SetupCompositor() { FML_CHECK(surface_) << "Set up the Vulkan surface before setting up a compositor."; compositor_ = std::make_unique( - surface_size_, context_->GetGrDirectContext()); + surface_size_, vulkan_context_->GetGrDirectContext()); } } // namespace testing diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.h b/shell/platform/embedder/tests/embedder_test_context_vulkan.h index d5cfc71b3e4cd..b08aa43941708 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.h +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONTEXT_VULKAN_H_ #define FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONTEXT_VULKAN_H_ +#include #include "flutter/shell/platform/embedder/tests/embedder_test_context.h" #include "flutter/testing/test_vulkan_context.h" #include "flutter/vulkan/vulkan_application.h" @@ -33,7 +34,6 @@ class EmbedderTestContextVulkan : public EmbedderTestContext { bool PresentImage(VkImage image); private: - std::unique_ptr context_; std::unique_ptr surface_; SkISize surface_size_ = SkISize::MakeEmpty(); diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index ba84f95c0cfc2..31a4a3ae791a3 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -10,8 +10,6 @@ #include "vulkan/vulkan.h" -#include "embedder.h" -#include "embedder_engine.h" #include "flutter/flow/raster_cache.h" #include "flutter/fml/file.h" #include "flutter/fml/make_copyable.h" @@ -1362,16 +1360,17 @@ TEST_F(EmbedderTest, CanRenderGradientWithCompositorWithXform) { ASSERT_TRUE(ImageMatchesFixture("gradient_xform.png", rendered_scene)); } -TEST_F(EmbedderTest, CanRenderGradientWithCompositorOnNonRootLayer) { - auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext); +TEST_P(EmbedderTestMultiBackend, + CanRenderGradientWithCompositorOnNonRootLayer) { + EmbedderTestContextType backend = GetParam(); + auto& context = GetEmbedderContext(backend); EmbedderConfigBuilder builder(context); builder.SetDartEntrypoint("render_gradient_on_non_root_backing_store"); - builder.SetOpenGLRendererConfig(SkISize::Make(800, 600)); + builder.SetRendererConfig(backend, SkISize::Make(800, 600)); builder.SetCompositor(); - builder.SetRenderTargetType( - EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLFramebuffer); + builder.SetRenderTargetType(GetTargetFromBackend(backend, true)); context.GetCompositor().SetNextPresentCallback( [&](const FlutterLayer** layers, size_t layers_count) { @@ -1380,9 +1379,8 @@ TEST_F(EmbedderTest, CanRenderGradientWithCompositorOnNonRootLayer) { // Layer Root { FlutterBackingStore backing_store = *layers[0]->backing_store; - backing_store.type = kFlutterBackingStoreTypeOpenGL; backing_store.did_update = true; - backing_store.open_gl.type = kFlutterOpenGLTargetTypeFramebuffer; + ConfigureBackingStore(backing_store, backend, true); FlutterLayer layer = {}; layer.struct_size = sizeof(layer); @@ -1413,9 +1411,8 @@ TEST_F(EmbedderTest, CanRenderGradientWithCompositorOnNonRootLayer) { // Layer 2 { FlutterBackingStore backing_store = *layers[2]->backing_store; - backing_store.type = kFlutterBackingStoreTypeOpenGL; backing_store.did_update = true; - backing_store.open_gl.type = kFlutterOpenGLTargetTypeFramebuffer; + ConfigureBackingStore(backing_store, backend, true); FlutterLayer layer = {}; layer.struct_size = sizeof(layer); @@ -1464,7 +1461,8 @@ TEST_F(EmbedderTest, CanRenderGradientWithCompositorOnNonRootLayer) { ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); - ASSERT_TRUE(ImageMatchesFixture("gradient.png", rendered_scene)); + ASSERT_TRUE(ImageMatchesFixture(ImagePrefix(backend, "gradient.png"), + rendered_scene)); } TEST_F(EmbedderTest, CanRenderGradientWithCompositorOnNonRootLayerWithXform) { diff --git a/shell/platform/embedder/tests/embedder_unittests_util.cc b/shell/platform/embedder/tests/embedder_unittests_util.cc index 09c2fa2ee3256..d0a114a792992 100644 --- a/shell/platform/embedder/tests/embedder_unittests_util.cc +++ b/shell/platform/embedder/tests/embedder_unittests_util.cc @@ -6,6 +6,7 @@ #include +#include "flutter/shell/platform/embedder/tests/embedder_test_backingstore_producer.h" #include "flutter/shell/platform/embedder/tests/embedder_unittests_util.h" namespace flutter { @@ -99,6 +100,31 @@ EmbedderTestBackingStoreProducer::RenderTargetType GetTargetFromBackend( } } +void ConfigureBackingStore(FlutterBackingStore& backing_store, + EmbedderTestContextType backend, + bool opengl_framebuffer) { + switch (backend) { + case EmbedderTestContextType::kVulkanContext: + backing_store.type = kFlutterBackingStoreTypeVulkan; + break; + case EmbedderTestContextType::kOpenGLContext: + if (opengl_framebuffer) { + backing_store.type = kFlutterBackingStoreTypeOpenGL; + backing_store.open_gl.type = kFlutterOpenGLTargetTypeFramebuffer; + } else { + backing_store.type = kFlutterBackingStoreTypeOpenGL; + backing_store.open_gl.type = kFlutterOpenGLTargetTypeTexture; + } + break; + case EmbedderTestContextType::kMetalContext: + backing_store.type = kFlutterBackingStoreTypeMetal; + break; + case EmbedderTestContextType::kSoftwareContext: + backing_store.type = kFlutterBackingStoreTypeSoftware; + break; + } +} + bool WriteImageToDisk(const fml::UniqueFD& directory, const std::string& name, sk_sp image) { diff --git a/shell/platform/embedder/tests/embedder_unittests_util.h b/shell/platform/embedder/tests/embedder_unittests_util.h index 4fa04ad3e57b0..227e3bca97d85 100644 --- a/shell/platform/embedder/tests/embedder_unittests_util.h +++ b/shell/platform/embedder/tests/embedder_unittests_util.h @@ -9,7 +9,6 @@ #include -#include "embedder.h" #include "flutter/fml/mapping.h" #include "flutter/fml/message_loop.h" #include "flutter/fml/paths.h" @@ -33,6 +32,10 @@ EmbedderTestBackingStoreProducer::RenderTargetType GetTargetFromBackend( EmbedderTestContextType backend, bool opengl_framebuffer); +void ConfigureBackingStore(FlutterBackingStore& backing_store, + EmbedderTestContextType backend, + bool opengl_framebuffer); + bool WriteImageToDisk(const fml::UniqueFD& directory, const std::string& name, sk_sp image); From 0e9017278f994c9cb9884cb872dbef9f7ce0ac1c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 14 Dec 2021 04:13:20 -0800 Subject: [PATCH 30/60] Format --- shell/platform/embedder/tests/embedder_test_context.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_test_context.h b/shell/platform/embedder/tests/embedder_test_context.h index 907fa332435a3..d5081626f523f 100644 --- a/shell/platform/embedder/tests/embedder_test_context.h +++ b/shell/platform/embedder/tests/embedder_test_context.h @@ -106,11 +106,11 @@ class EmbedderTestContext { using NextSceneCallback = std::function image)>; - #ifdef SHELL_ENABLE_VULKAN +#ifdef SHELL_ENABLE_VULKAN // The TestVulkanContext destructor must be called _after_ the compositor is // freed. std::unique_ptr vulkan_context_ = nullptr; - #endif +#endif std::string assets_path_; ELFAOTSymbols aot_symbols_; From a5f7ec7b9e7043cb545fb780b186b0b4eabc4807 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 14 Dec 2021 14:43:33 -0800 Subject: [PATCH 31/60] Parameterize CanCreateEmbedderWithCustomRenderTaskRunnerTheSameAsPlatformTaskRunner --- shell/platform/embedder/tests/embedder_unittests_gl.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 31a4a3ae791a3..59fa7b749d656 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -1737,7 +1737,7 @@ TEST_F(EmbedderTest, CanCreateEmbedderWithCustomRenderTaskRunner) { /// Asserts that the render task runner can be the same as the platform task /// runner. /// -TEST_F(EmbedderTest, +TEST_P(EmbedderTestMultiBackend, CanCreateEmbedderWithCustomRenderTaskRunnerTheSameAsPlatformTaskRunner) { // A new thread needs to be created for the platform thread because the test // can't wait for assertions to be completed on the same thread that services @@ -1759,10 +1759,10 @@ TEST_F(EmbedderTest, }); platform_task_runner->PostTask([&]() { - EmbedderConfigBuilder builder( - GetEmbedderContext(EmbedderTestContextType::kOpenGLContext)); + EmbedderTestContextType backend = GetParam(); + EmbedderConfigBuilder builder(GetEmbedderContext(backend)); builder.SetDartEntrypoint("can_render_scene_without_custom_compositor"); - builder.SetOpenGLRendererConfig(SkISize::Make(800, 600)); + builder.SetRendererConfig(backend, SkISize::Make(800, 600)); builder.SetRenderTaskRunner( &common_task_runner.GetFlutterTaskRunnerDescription()); builder.SetPlatformTaskRunner( From 3fa15981ae3fa2b990c65472f1c3c32f77138ea4 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 14 Dec 2021 15:03:55 -0800 Subject: [PATCH 32/60] Parameterize CompositorMustBeAbleToRenderKnownScenePixelRatioOnSurface --- ci/licenses_golden/licenses_flutter | 1 + shell/platform/embedder/BUILD.gn | 1 + .../embedder/fixtures/vk_dpr_noxform.png | Bin 0 -> 37208 bytes .../embedder/tests/embedder_unittests_gl.cc | 19 +++++++++--------- 4 files changed, 11 insertions(+), 10 deletions(-) create mode 100644 shell/platform/embedder/fixtures/vk_dpr_noxform.png diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 95efaddf54bc9..21443efbc68e6 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1389,6 +1389,7 @@ FILE: ../../../flutter/shell/platform/embedder/fixtures/scene_without_custom_com FILE: ../../../flutter/shell/platform/embedder/fixtures/snapshot_large_scene.png FILE: ../../../flutter/shell/platform/embedder/fixtures/verifyb143464703.png FILE: ../../../flutter/shell/platform/embedder/fixtures/verifyb143464703_soft_noxform.png +FILE: ../../../flutter/shell/platform/embedder/fixtures/vk_dpr_noxform.png FILE: ../../../flutter/shell/platform/embedder/fixtures/vk_gradient.png FILE: ../../../flutter/shell/platform/embedder/platform_view_embedder.cc FILE: ../../../flutter/shell/platform/embedder/platform_view_embedder.h diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index c32e465eebd1b..1e6ac775d5e82 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -175,6 +175,7 @@ test_fixtures("fixtures") { "fixtures/dpr_noxform.png", "fixtures/dpr_xform.png", "fixtures/gradient.png", + "fixtures/vk_dpr_noxform.png", "fixtures/vk_gradient.png", "fixtures/gradient_metal.png", "fixtures/external_texture_metal.png", diff --git a/shell/platform/embedder/fixtures/vk_dpr_noxform.png b/shell/platform/embedder/fixtures/vk_dpr_noxform.png new file mode 100644 index 0000000000000000000000000000000000000000..7f5c28ba808fd59714b7cfe1113478d25ce02863 GIT binary patch literal 37208 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 literal 0 HcmV?d00001 diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 59fa7b749d656..378337424172d 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -1812,17 +1812,17 @@ TEST_P(EmbedderTestMultiBackend, } } -TEST_F(EmbedderTest, +TEST_P(EmbedderTestMultiBackend, CompositorMustBeAbleToRenderKnownScenePixelRatioOnSurface) { - auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext); + EmbedderTestContextType backend = GetParam(); + auto& context = GetEmbedderContext(backend); EmbedderConfigBuilder builder(context); - builder.SetOpenGLRendererConfig(SkISize::Make(800, 600)); + builder.SetRendererConfig(backend, SkISize::Make(800, 600)); builder.SetCompositor(); builder.SetDartEntrypoint("can_display_platform_view_with_pixel_ratio"); - builder.SetRenderTargetType( - EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLTexture); + builder.SetRenderTargetType(GetTargetFromBackend(backend, false)); fml::CountDownLatch latch(1); @@ -1835,9 +1835,8 @@ TEST_F(EmbedderTest, // Layer 0 (Root) { FlutterBackingStore backing_store = *layers[0]->backing_store; - backing_store.type = kFlutterBackingStoreTypeOpenGL; backing_store.did_update = true; - backing_store.open_gl.type = kFlutterOpenGLTargetTypeTexture; + ConfigureBackingStore(backing_store, backend, false); FlutterLayer layer = {}; layer.struct_size = sizeof(layer); @@ -1868,9 +1867,8 @@ TEST_F(EmbedderTest, // Layer 2 { FlutterBackingStore backing_store = *layers[2]->backing_store; - backing_store.type = kFlutterBackingStoreTypeOpenGL; backing_store.did_update = true; - backing_store.open_gl.type = kFlutterOpenGLTargetTypeTexture; + ConfigureBackingStore(backing_store, backend, false); FlutterLayer layer = {}; layer.struct_size = sizeof(layer); @@ -1899,7 +1897,8 @@ TEST_F(EmbedderTest, latch.Wait(); - ASSERT_TRUE(ImageMatchesFixture("dpr_noxform.png", rendered_scene)); + ASSERT_TRUE(ImageMatchesFixture(ImagePrefix(backend, "dpr_noxform.png"), + rendered_scene)); } TEST_F( From 9f49cb0ad47b0bd431dfe4df1c716deb5d6eea52 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 14 Dec 2021 17:59:38 -0800 Subject: [PATCH 33/60] Parameterize PlatformViewMutatorsAreValid, intrusively refcount TestVulkanContext, force lifetime of Vulkan context to extend past all test harness images, add missing header guard --- .../tests/embedder_test_backingstore_producer.cc | 2 +- .../tests/embedder_test_backingstore_producer.h | 3 ++- .../platform/embedder/tests/embedder_test_context.h | 2 +- .../embedder/tests/embedder_test_context_vulkan.cc | 2 +- .../embedder/tests/embedder_unittests_gl.cc | 13 ++++++------- testing/test_vulkan_context.cc | 4 ++++ testing/test_vulkan_context.h | 4 +++- testing/test_vulkan_image.cc | 2 ++ testing/test_vulkan_image.h | 9 +++++++++ 9 files changed, 29 insertions(+), 12 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc index 63e775aebfb5a..2ed3292dff44f 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc @@ -25,7 +25,7 @@ EmbedderTestBackingStoreProducer::EmbedderTestBackingStoreProducer( #endif #ifdef SHELL_ENABLE_VULKAN , - test_vulkan_context_(std::make_unique()) + test_vulkan_context_(fml::MakeRefCounted()) #endif { } diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h index f1ba8469f38af..b35c04d55bb68 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h @@ -7,6 +7,7 @@ #include #include "flutter/fml/macros.h" +#include "flutter/fml/memory/ref_ptr_internal.h" #include "flutter/shell/platform/embedder/embedder.h" #include "third_party/skia/include/gpu/GrDirectContext.h" @@ -62,7 +63,7 @@ class EmbedderTestBackingStoreProducer { #endif #ifdef SHELL_ENABLE_VULKAN - std::unique_ptr test_vulkan_context_; + fml::RefPtr test_vulkan_context_; #endif FML_DISALLOW_COPY_AND_ASSIGN(EmbedderTestBackingStoreProducer); diff --git a/shell/platform/embedder/tests/embedder_test_context.h b/shell/platform/embedder/tests/embedder_test_context.h index d5081626f523f..f7df168122a3d 100644 --- a/shell/platform/embedder/tests/embedder_test_context.h +++ b/shell/platform/embedder/tests/embedder_test_context.h @@ -109,7 +109,7 @@ class EmbedderTestContext { #ifdef SHELL_ENABLE_VULKAN // The TestVulkanContext destructor must be called _after_ the compositor is // freed. - std::unique_ptr vulkan_context_ = nullptr; + fml::RefPtr vulkan_context_ = nullptr; #endif std::string assets_path_; diff --git a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc index a92a6cc88d8e1..0fb93fa1e367c 100644 --- a/shell/platform/embedder/tests/embedder_test_context_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -19,7 +19,7 @@ namespace testing { EmbedderTestContextVulkan::EmbedderTestContextVulkan(std::string assets_path) : EmbedderTestContext(assets_path), surface_() { - vulkan_context_ = std::make_unique(); + vulkan_context_ = fml::MakeRefCounted(); } EmbedderTestContextVulkan::~EmbedderTestContextVulkan() {} diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 378337424172d..9ccbe816b0883 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -2082,16 +2082,16 @@ TEST_F(EmbedderTest, FlutterEngineShutdown(engine.release()); } -TEST_F(EmbedderTest, PlatformViewMutatorsAreValid) { - auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext); +TEST_P(EmbedderTestMultiBackend, PlatformViewMutatorsAreValid) { + EmbedderTestContextType backend = GetParam(); + auto& context = GetEmbedderContext(backend); EmbedderConfigBuilder builder(context); - builder.SetOpenGLRendererConfig(SkISize::Make(800, 600)); + builder.SetRendererConfig(backend, SkISize::Make(800, 600)); builder.SetCompositor(); builder.SetDartEntrypoint("platform_view_mutators"); - builder.SetRenderTargetType( - EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLTexture); + builder.SetRenderTargetType(GetTargetFromBackend(backend, false)); fml::CountDownLatch latch(1); context.GetCompositor().SetNextPresentCallback( @@ -2101,9 +2101,8 @@ TEST_F(EmbedderTest, PlatformViewMutatorsAreValid) { // Layer 0 (Root) { FlutterBackingStore backing_store = *layers[0]->backing_store; - backing_store.type = kFlutterBackingStoreTypeOpenGL; backing_store.did_update = true; - backing_store.open_gl.type = kFlutterOpenGLTargetTypeTexture; + ConfigureBackingStore(backing_store, backend, false); FlutterLayer layer = {}; layer.struct_size = sizeof(layer); diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index 4d424b7c10270..ec6be6b1a5c06 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -9,6 +9,7 @@ #include "flutter/shell/common/context_options.h" #include "flutter/testing/test_vulkan_context.h" +#include "fml/memory/ref_ptr.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/vk/GrVkExtensions.h" @@ -154,6 +155,9 @@ std::optional TestVulkanContext::CreateImage( return std::nullopt; } + result.context_ = + fml::RefPtr(const_cast(this)); + return result; } diff --git a/testing/test_vulkan_context.h b/testing/test_vulkan_context.h index d828a7258e18a..04298003a2741 100644 --- a/testing/test_vulkan_context.h +++ b/testing/test_vulkan_context.h @@ -18,7 +18,7 @@ namespace flutter { namespace testing { -class TestVulkanContext { +class TestVulkanContext : public fml::RefCountedThreadSafe { public: TestVulkanContext(); @@ -36,6 +36,8 @@ class TestVulkanContext { friend class EmbedderTestContextVulkan; friend class EmbedderConfigBuilder; + FML_FRIEND_MAKE_REF_COUNTED(TestVulkanContext); + FML_FRIEND_REF_COUNTED_THREAD_SAFE(TestVulkanContext); FML_DISALLOW_COPY_AND_ASSIGN(TestVulkanContext); }; diff --git a/testing/test_vulkan_image.cc b/testing/test_vulkan_image.cc index f4bf01ac87923..4c365412ae6ec 100644 --- a/testing/test_vulkan_image.cc +++ b/testing/test_vulkan_image.cc @@ -4,6 +4,8 @@ #include "flutter/testing/test_vulkan_image.h" +#include "flutter/testing/test_vulkan_context.h" + namespace flutter { namespace testing { diff --git a/testing/test_vulkan_image.h b/testing/test_vulkan_image.h index 33b497cfb0205..c8a6a797f385e 100644 --- a/testing/test_vulkan_image.h +++ b/testing/test_vulkan_image.h @@ -2,9 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef FLUTTER_TESTING_TEST_VULKAN_IMAGE_H_ +#define FLUTTER_TESTING_TEST_VULKAN_IMAGE_H_ + #include "flutter/fml/macros.h" #include "flutter/vulkan/vulkan_handle.h" +#include "flutter/fml/memory/ref_ptr.h" #include "third_party/skia/include/core/SkSize.h" namespace flutter { @@ -25,6 +29,9 @@ class TestVulkanImage { private: TestVulkanImage(); + // The lifetime of the Vulkan state must exceed memory/image handles. + fml::RefPtr context_; + vulkan::VulkanHandle image_; vulkan::VulkanHandle memory_; @@ -35,3 +42,5 @@ class TestVulkanImage { } // namespace testing } // namespace flutter + +#endif // FLUTTER_TESTING_TEST_VULKAN_IMAGE_H_ From f98c46c1b4992eea1beccb9c365153549dc81ee1 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 15 Dec 2021 18:05:58 -0800 Subject: [PATCH 34/60] Make FlutterVulkanImageHandle a uint64_t and internally cast to VkImage --- shell/platform/embedder/embedder.cc | 6 +++--- shell/platform/embedder/embedder.h | 2 +- shell/platform/embedder/tests/embedder_config_builder.cc | 2 +- .../embedder/tests/embedder_test_backingstore_producer.cc | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index bc08816398b80..0da3d99a721df 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -440,7 +440,7 @@ InferVulkanPlatformViewCreationCallback( }; FlutterVulkanImage vulkan_image = ptr(user_data, &frame_info); - return static_cast(vulkan_image.image); + return reinterpret_cast(vulkan_image.image); }; auto vulkan_present_image_callback = @@ -448,7 +448,7 @@ InferVulkanPlatformViewCreationCallback( user_data](VkImage image) -> bool { FlutterVulkanImage image_desc = { .struct_size = sizeof(FlutterVulkanImage), - .image = image, + .image = reinterpret_cast(image), }; return ptr(user_data, &image_desc); }; @@ -742,7 +742,7 @@ static sk_sp MakeSkSurfaceFromBackingStore( } GrVkImageInfo image_info = { - .fImage = static_cast(vulkan->image.image), + .fImage = reinterpret_cast(vulkan->image.image), .fImageTiling = VK_IMAGE_TILING_OPTIMAL, .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, .fFormat = VK_FORMAT_R8G8B8A8_UNORM, diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index b401638d18568..253612b4912ef 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -555,7 +555,7 @@ typedef void* FlutterVulkanDeviceHandle; typedef void* FlutterVulkanQueueHandle; /// Alias for VkImage. -typedef void* FlutterVulkanImageHandle; +typedef uint64_t FlutterVulkanImageHandle; typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanImage). diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 07e251391992d..9e9b3aec115a1 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -503,7 +503,7 @@ void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { static_cast(frame_info->size.height)}); return { .struct_size = sizeof(FlutterVulkanImage), - .image = image, + .image = reinterpret_cast(image), }; }; vulkan_renderer_config_.present_image_callback = diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc index 2ed3292dff44f..af40ac2bd138b 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc @@ -285,7 +285,8 @@ bool EmbedderTestBackingStoreProducer::CreateVulkanImage( backing_store_out->type = kFlutterBackingStoreTypeVulkan; backing_store_out->user_data = surface.get(); backing_store_out->vulkan.user_data = surface.get(); - backing_store_out->vulkan.image.image = image_info.fImage; + backing_store_out->vulkan.image.image = + reinterpret_cast(image_info.fImage); backing_store_out->vulkan.destruction_callback = [](void* user_data) { reinterpret_cast(user_data)->unref(); }; From 2f4927cbee1d4f155aa6026de8316d061fd97cb6 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 6 Jan 2022 13:16:51 -0800 Subject: [PATCH 35/60] Add format field to FlutterVulkanImage --- shell/gpu/BUILD.gn | 4 +- shell/gpu/gpu_surface_vulkan.cc | 44 +++++++++++++------ shell/gpu/gpu_surface_vulkan.h | 5 ++- shell/gpu/gpu_surface_vulkan_delegate.h | 5 ++- shell/platform/embedder/embedder.cc | 20 ++++----- shell/platform/embedder/embedder.h | 2 + .../embedder/embedder_surface_vulkan.cc | 6 +-- .../embedder/embedder_surface_vulkan.h | 11 ++--- .../embedder/tests/embedder_assertions.h | 4 +- .../embedder/tests/embedder_config_builder.cc | 2 + .../embedder_test_backingstore_producer.cc | 1 + 11 files changed, 66 insertions(+), 38 deletions(-) diff --git a/shell/gpu/BUILD.gn b/shell/gpu/BUILD.gn index 4449f084bf23b..ec1d377d963f7 100644 --- a/shell/gpu/BUILD.gn +++ b/shell/gpu/BUILD.gn @@ -43,8 +43,8 @@ source_set("gpu_surface_vulkan") { "gpu_surface_vulkan_delegate.cc", "gpu_surface_vulkan_delegate.h", ] - - deps = gpu_common_deps + deps = [ "//flutter/shell/platform/embedder:embedder_headers" ] + deps += gpu_common_deps public_deps = [ "//flutter/vulkan" ] } diff --git a/shell/gpu/gpu_surface_vulkan.cc b/shell/gpu/gpu_surface_vulkan.cc index d7537b4d35899..6040f459cc012 100644 --- a/shell/gpu/gpu_surface_vulkan.cc +++ b/shell/gpu/gpu_surface_vulkan.cc @@ -7,6 +7,7 @@ #include "flutter/fml/logging.h" #include "fml/trace_event.h" #include "include/core/SkSize.h" +#include "third_party/swiftshader/include/vulkan/vulkan_core.h" namespace flutter { @@ -44,13 +45,15 @@ std::unique_ptr GPUSurfaceVulkan::AcquireFrame( }); } - VkImage image = delegate_->AcquireImage(frame_size); - if (!image) { + FlutterVulkanImage image = delegate_->AcquireImage(frame_size); + if (!image.image) { FML_LOG(ERROR) << "Invalid VkImage given by the embedder."; return nullptr; } - sk_sp surface = CreateSurfaceFromVulkanImage(image, frame_size); + sk_sp surface = CreateSurfaceFromVulkanImage( + reinterpret_cast(image.image), + static_cast(image.format), frame_size); if (!surface) { FML_LOG(ERROR) << "Could not create the SkSurface from the Vulkan image."; return nullptr; @@ -67,7 +70,8 @@ std::unique_ptr GPUSurfaceVulkan::AcquireFrame( canvas->flush(); - return delegate->PresentImage(image); + return delegate->PresentImage(reinterpret_cast(image.image), + static_cast(image.format)); }; SurfaceFrame::FramebufferInfo framebuffer_info{.supports_readback = true}; @@ -89,13 +93,14 @@ GrDirectContext* GPUSurfaceVulkan::GetContext() { } sk_sp GPUSurfaceVulkan::CreateSurfaceFromVulkanImage( - VkImage image, + const VkImage image, + const VkFormat format, const SkISize& size) { GrVkImageInfo image_info = { .fImage = image, .fImageTiling = VK_IMAGE_TILING_OPTIMAL, .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .fFormat = VK_FORMAT_R8G8B8A8_UNORM, + .fFormat = format, .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | @@ -111,14 +116,27 @@ sk_sp GPUSurfaceVulkan::CreateSurfaceFromVulkanImage( SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); return SkSurface::MakeFromBackendTexture( - skia_context_.get(), // context - backend_texture, // back-end texture - kTopLeft_GrSurfaceOrigin, // surface origin - 1, // sample count - kRGBA_8888_SkColorType, // color type - SkColorSpace::MakeSRGB(), // color space - &surface_properties // surface properties + skia_context_.get(), // context + backend_texture, // back-end texture + kTopLeft_GrSurfaceOrigin, // surface origin + 1, // sample count + ColorTypeFromFormat(format), // color type + SkColorSpace::MakeSRGB(), // color space + &surface_properties // surface properties ); } +SkColorType GPUSurfaceVulkan::ColorTypeFromFormat(const VkFormat format) { + switch (format) { + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_R8G8B8A8_SRGB: + return SkColorType::kRGBA_8888_SkColorType; + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_B8G8R8A8_SRGB: + return SkColorType::kBGRA_8888_SkColorType; + default: + return SkColorType::kUnknown_SkColorType; + } +} + } // namespace flutter diff --git a/shell/gpu/gpu_surface_vulkan.h b/shell/gpu/gpu_surface_vulkan.h index 3baf890a0158f..b281ac8c0f160 100644 --- a/shell/gpu/gpu_surface_vulkan.h +++ b/shell/gpu/gpu_surface_vulkan.h @@ -46,6 +46,8 @@ class GPUSurfaceVulkan : public Surface { // |Surface| GrDirectContext* GetContext() override; + static SkColorType ColorTypeFromFormat(const VkFormat format); + private: GPUSurfaceVulkanDelegate* delegate_; sk_sp skia_context_; @@ -53,7 +55,8 @@ class GPUSurfaceVulkan : public Surface { fml::WeakPtrFactory weak_factory_; - sk_sp CreateSurfaceFromVulkanImage(VkImage image, + sk_sp CreateSurfaceFromVulkanImage(const VkImage image, + const VkFormat format, const SkISize& size); FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceVulkan); diff --git a/shell/gpu/gpu_surface_vulkan_delegate.h b/shell/gpu/gpu_surface_vulkan_delegate.h index 6e18204904cc5..023fe9261900b 100644 --- a/shell/gpu/gpu_surface_vulkan_delegate.h +++ b/shell/gpu/gpu_surface_vulkan_delegate.h @@ -6,6 +6,7 @@ #define FLUTTER_SHELL_GPU_GPU_SURFACE_VULKAN_DELEGATE_H_ #include "flutter/fml/memory/ref_ptr.h" +#include "flutter/shell/platform/embedder/embedder.h" #include "flutter/vulkan/vulkan_device.h" #include "flutter/vulkan/vulkan_image.h" #include "flutter/vulkan/vulkan_proc_table.h" @@ -36,12 +37,12 @@ class GPUSurfaceVulkanDelegate { /// @brief Called by the engine to fetch a VkImage for writing the next /// frame. /// - virtual VkImage AcquireImage(const SkISize& size) = 0; + virtual FlutterVulkanImage AcquireImage(const SkISize& size) = 0; /// @brief Called by the engine once a frame has been rendered to the image /// and it's ready to be bound for further reading/writing. /// - virtual bool PresentImage(VkImage image) = 0; + virtual bool PresentImage(VkImage image, VkFormat format) = 0; }; } // namespace flutter diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 0da3d99a721df..8b84430213ca2 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -432,23 +432,23 @@ InferVulkanPlatformViewCreationCallback( auto vulkan_get_next_image = [ptr = config->vulkan.get_next_image_callback, - user_data](const SkISize& frame_size) -> VkImage { + user_data](const SkISize& frame_size) -> FlutterVulkanImage { FlutterFrameInfo frame_info = { .struct_size = sizeof(FlutterFrameInfo), .size = {static_cast(frame_size.width()), static_cast(frame_size.height())}, }; - FlutterVulkanImage vulkan_image = ptr(user_data, &frame_info); - return reinterpret_cast(vulkan_image.image); + return ptr(user_data, &frame_info); }; auto vulkan_present_image_callback = - [ptr = config->vulkan.present_image_callback, - user_data](VkImage image) -> bool { + [ptr = config->vulkan.present_image_callback, user_data]( + VkImage image, VkFormat format) -> bool { FlutterVulkanImage image_desc = { .struct_size = sizeof(FlutterVulkanImage), .image = reinterpret_cast(image), + .format = format, }; return ptr(user_data, &image_desc); }; @@ -740,12 +740,11 @@ static sk_sp MakeSkSurfaceFromBackingStore( FML_LOG(ERROR) << "Embedder supplied null Vulkan image."; return nullptr; } - GrVkImageInfo image_info = { .fImage = reinterpret_cast(vulkan->image.image), .fImageTiling = VK_IMAGE_TILING_OPTIMAL, .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .fFormat = VK_FORMAT_R8G8B8A8_UNORM, + .fFormat = static_cast(vulkan->image.format), .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | @@ -765,9 +764,10 @@ static sk_sp MakeSkSurfaceFromBackingStore( backend_texture, // back-end texture kTopLeft_GrSurfaceOrigin, // surface origin 1, // sample count - kRGBA_8888_SkColorType, // color type - SkColorSpace::MakeSRGB(), // color space - &surface_properties, // surface properties + flutter::GPUSurfaceVulkan::ColorTypeFromFormat( + static_cast(vulkan->image.format)), // color type + SkColorSpace::MakeSRGB(), // color space + &surface_properties, // surface properties static_cast( vulkan->destruction_callback), // release proc vulkan->user_data // release context diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 253612b4912ef..88f3c499399c9 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -563,6 +563,8 @@ typedef struct { /// Handle to the VkImage that is owned by the embedder. The engine will /// bind this image for writing the frame. FlutterVulkanImageHandle image; + /// The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM). + uint32_t format; } FlutterVulkanImage; /// Callback to fetch a Vulkan function pointer for a given instance. Normally, diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index b4a299a65eddc..6a6455a948288 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -63,13 +63,13 @@ const vulkan::VulkanProcTable& EmbedderSurfaceVulkan::vk() { } // |GPUSurfaceVulkanDelegate| -VkImage EmbedderSurfaceVulkan::AcquireImage(const SkISize& size) { +FlutterVulkanImage EmbedderSurfaceVulkan::AcquireImage(const SkISize& size) { return vulkan_dispatch_table_.get_next_image(size); } // |GPUSurfaceVulkanDelegate| -bool EmbedderSurfaceVulkan::PresentImage(VkImage image) { - return vulkan_dispatch_table_.present_image(image); +bool EmbedderSurfaceVulkan::PresentImage(VkImage image, VkFormat format) { + return vulkan_dispatch_table_.present_image(image, format); } // |EmbedderSurface| diff --git a/shell/platform/embedder/embedder_surface_vulkan.h b/shell/platform/embedder/embedder_surface_vulkan.h index 6bce55005d2a2..12c0791822edd 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.h +++ b/shell/platform/embedder/embedder_surface_vulkan.h @@ -22,9 +22,10 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface, struct VulkanDispatchTable { std::function get_instance_proc_address; // required - std::function - get_next_image; // required - std::function present_image; // required + std::function + get_next_image; // required + std::function + present_image; // required }; EmbedderSurfaceVulkan( @@ -42,10 +43,10 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface, const vulkan::VulkanProcTable& vk() override; // |GPUSurfaceVulkanDelegate| - VkImage AcquireImage(const SkISize& size) override; + FlutterVulkanImage AcquireImage(const SkISize& size) override; // |GPUSurfaceVulkanDelegate| - bool PresentImage(VkImage image) override; + bool PresentImage(VkImage image, VkFormat format) override; private: bool valid_ = false; diff --git a/shell/platform/embedder/tests/embedder_assertions.h b/shell/platform/embedder/tests/embedder_assertions.h index 7c4f877533c93..e631305852ac9 100644 --- a/shell/platform/embedder/tests/embedder_assertions.h +++ b/shell/platform/embedder/tests/embedder_assertions.h @@ -72,7 +72,7 @@ inline bool operator==(const FlutterMetalTexture& a, inline bool operator==(const FlutterVulkanImage& a, const FlutterVulkanImage& b) { - return a.image == b.image; + return a.image == b.image && a.format == b.format; } inline bool operator==(const FlutterVulkanBackingStore& a, @@ -274,7 +274,7 @@ inline std::ostream& operator<<(std::ostream& out, inline std::ostream& operator<<(std::ostream& out, const FlutterVulkanImage& item) { return out << "(FlutterVulkanTexture) Image Handle: " << std::hex - << item.image; + << item.image << std::dec << " Format: " << item.format; } inline std::string FlutterPlatformViewMutationTypeToString( diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 9e9b3aec115a1..2cbbf90f68115 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -8,6 +8,7 @@ #include "flutter/shell/platform/embedder/embedder.h" #include "tests/embedder_test_context.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/swiftshader/include/vulkan/vulkan_core.h" #ifdef SHELL_ENABLE_GL #include "flutter/shell/platform/embedder/tests/embedder_test_compositor_gl.h" @@ -504,6 +505,7 @@ void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { return { .struct_size = sizeof(FlutterVulkanImage), .image = reinterpret_cast(image), + .format = VK_FORMAT_R8G8B8A8_UNORM, }; }; vulkan_renderer_config_.present_image_callback = diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc index af40ac2bd138b..e74258cdf6105 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc @@ -287,6 +287,7 @@ bool EmbedderTestBackingStoreProducer::CreateVulkanImage( backing_store_out->vulkan.user_data = surface.get(); backing_store_out->vulkan.image.image = reinterpret_cast(image_info.fImage); + backing_store_out->vulkan.image.format = VK_FORMAT_R8G8B8A8_UNORM; backing_store_out->vulkan.destruction_callback = [](void* user_data) { reinterpret_cast(user_data)->unref(); }; From 1624ffa982d8d38781be9a03089c2734bdeda2d7 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 6 Jan 2022 14:00:17 -0800 Subject: [PATCH 36/60] Add format cast to make windows targets happy --- shell/platform/embedder/embedder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 8b84430213ca2..a933b0ccc7e51 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -448,7 +448,7 @@ InferVulkanPlatformViewCreationCallback( FlutterVulkanImage image_desc = { .struct_size = sizeof(FlutterVulkanImage), .image = reinterpret_cast(image), - .format = format, + .format = static_cast(format), }; return ptr(user_data, &image_desc); }; From d8c70038c281aac2219848244dc2b16b4779497a Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 6 Jan 2022 14:45:59 -0800 Subject: [PATCH 37/60] Add Vulkan version parameter to FlutterVulkanRendererConfig --- shell/platform/embedder/embedder.cc | 1 + shell/platform/embedder/embedder.h | 15 +++++++++++---- .../platform/embedder/embedder_surface_vulkan.cc | 11 +++++++---- shell/platform/embedder/embedder_surface_vulkan.h | 2 ++ .../embedder/tests/embedder_config_builder.cc | 3 +++ 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index a933b0ccc7e51..4c3ecdeec597c 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -464,6 +464,7 @@ InferVulkanPlatformViewCreationCallback( std::unique_ptr embedder_surface = std::make_unique( + config->vulkan.version, static_cast(config->vulkan.instance), static_cast(config->vulkan.physical_device), static_cast(config->vulkan.device), diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 88f3c499399c9..28a9cff414669 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -588,23 +588,30 @@ typedef bool (*FlutterVulkanPresentCallback)( typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanRendererConfig). size_t struct_size; - // VkInstance handle. + + /// The Vulkan API version. This should match the value set in + /// VkApplicationInfo::apiVersion when the VkInstance was created. + uint32_t version; + /// VkInstance handle. FlutterVulkanInstanceHandle instance; - // VkPhysicalDevice handle. + /// VkPhysicalDevice handle. FlutterVulkanPhysicalDeviceHandle physical_device; - // VkDevice handle. + /// VkDevice handle. FlutterVulkanDeviceHandle device; + /// The queue family index of the VkQueue supplied in the next field. uint32_t queue_family_index; - // VkQueue handle. + /// VkQueue handle. FlutterVulkanQueueHandle queue; FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback; /// The callback invoked when the engine requests a VkImage from the embedder /// for rendering the next frame. + /// Not used if a FlutterCompositor is supplied in FlutterProjectArgs. FlutterVulkanImageCallback get_next_image_callback; /// The callback invoked when a VkImage has been written to and is ready for /// use by the embedder. Prior to calling this callback, the engine performs /// a host sync, and so the VkImage can be used in a pipeline by the embedder /// without any additional synchronization. + /// Not used if a FlutterCompositor is supplied in FlutterProjectArgs. FlutterVulkanPresentCallback present_image_callback; } FlutterVulkanRendererConfig; diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index 6a6455a948288..581b41c421287 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -14,6 +14,7 @@ namespace flutter { EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( + uint32_t version, VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, @@ -44,13 +45,14 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( return; } - main_context_ = CreateGrContext(instance, ContextType::kRender); + main_context_ = CreateGrContext(instance, version, ContextType::kRender); // TODO(bdero): Add a second (optional) queue+family index to the Embedder API // to allow embedders to specify a dedicated transfer queue for // use by the resource context. Queue families with graphics // capability can always be used for memory transferring, but it // would be adventageous to use a dedicated transter queue here. - resource_context_ = CreateGrContext(instance, ContextType::kResource); + resource_context_ = + CreateGrContext(instance, version, ContextType::kResource); valid_ = main_context_ && resource_context_; } @@ -91,6 +93,7 @@ sk_sp EmbedderSurfaceVulkan::CreateResourceContext() const { sk_sp EmbedderSurfaceVulkan::CreateGrContext( VkInstance instance, + uint32_t version, ContextType context_type) const { uint32_t skia_features = 0; if (!device_.GetPhysicalDeviceFeaturesSkia(&skia_features)) { @@ -113,8 +116,8 @@ sk_sp EmbedderSurfaceVulkan::CreateGrContext( backend_context.fDevice = device_.GetHandle(); backend_context.fQueue = device_.GetQueueHandle(); backend_context.fGraphicsQueueIndex = device_.GetGraphicsQueueIndex(); - backend_context.fMinAPIVersion = VK_MAKE_VERSION(1, 0, 0); - backend_context.fMaxAPIVersion = VK_MAKE_VERSION(1, 0, 0); + backend_context.fMinAPIVersion = version; + backend_context.fMaxAPIVersion = version; backend_context.fFeatures = skia_features; backend_context.fVkExtensions = &extensions; backend_context.fGetProc = get_proc; diff --git a/shell/platform/embedder/embedder_surface_vulkan.h b/shell/platform/embedder/embedder_surface_vulkan.h index 12c0791822edd..2248e783ddc5d 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.h +++ b/shell/platform/embedder/embedder_surface_vulkan.h @@ -29,6 +29,7 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface, }; EmbedderSurfaceVulkan( + uint32_t version, VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, @@ -67,6 +68,7 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface, sk_sp CreateResourceContext() const override; sk_sp CreateGrContext(VkInstance instance, + uint32_t version, ContextType context_type) const; void* GetInstanceProcAddress(VkInstance instance, const char* proc_name); diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 2cbbf90f68115..ae63a3220f41f 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -473,6 +473,9 @@ void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { } vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); + vulkan_renderer_config_.version = + static_cast(context_) + .vulkan_context_->application_->GetAPIVersion(); vulkan_renderer_config_.instance = static_cast(context_) .vulkan_context_->application_->GetInstance(); From 29af39c1aa45eb28bfad1cde4734929377c2d98d Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 6 Jan 2022 15:20:47 -0800 Subject: [PATCH 38/60] Fix cast --- shell/platform/embedder/embedder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 4c3ecdeec597c..cfe8854be9c61 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -448,7 +448,7 @@ InferVulkanPlatformViewCreationCallback( FlutterVulkanImage image_desc = { .struct_size = sizeof(FlutterVulkanImage), .image = reinterpret_cast(image), - .format = static_cast(format), + .format = static_cast(format), }; return ptr(user_data, &image_desc); }; From fec4c06983a71926ecaf8c6a11af90013e2e5aca Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 6 Jan 2022 15:21:50 -0800 Subject: [PATCH 39/60] Activate memory_requirements_2 if the Vulkan version is >= 1.1 --- shell/platform/embedder/embedder_surface_vulkan.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index 581b41c421287..661eaea23b566 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -123,17 +123,16 @@ sk_sp EmbedderSurfaceVulkan::CreateGrContext( backend_context.fGetProc = get_proc; backend_context.fOwnsInstanceAndDevice = false; - // TODO(bdero): Activate MEMORY_REQUIREMENTS_2 if available because VMA (the - // allocator used by Skia) knows how to take advantage of these - // features. - /* + // Activate MEMORY_REQUIREMENTS_2 (available in Vulkan >= 1.1) because VMA + // knows how to take advantage of these features. + if (version >= VK_MAKE_VERSION(1, 1, 0)) { const char* device_extensions[] = { VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, }; extensions.init(backend_context.fGetProc, backend_context.fInstance, - backend_context.fPhysicalDevice, 0, nullptr, - countof(device_extensions), device_extensions); - */ + backend_context.fPhysicalDevice, 0, nullptr, 1, + device_extensions); + } GrContextOptions options = MakeDefaultContextOptions(context_type, GrBackendApi::kVulkan); From 6e11d8a4fe01f7076f0aa7f3d18bde16b44eee60 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 6 Jan 2022 18:58:02 -0800 Subject: [PATCH 40/60] Allow the embedder to optionally supply enabled instance/device extensions; don't enable get_memory_requirements_2 automatically --- shell/platform/embedder/embedder.cc | 4 +++ shell/platform/embedder/embedder.h | 14 +++++++++ .../embedder/embedder_surface_vulkan.cc | 31 +++++++++++-------- .../embedder/embedder_surface_vulkan.h | 8 +++++ 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index cfe8854be9c61..21cfb992b0e76 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -466,6 +466,10 @@ InferVulkanPlatformViewCreationCallback( std::make_unique( config->vulkan.version, static_cast(config->vulkan.instance), + config->vulkan.instance_extension_count, + config->vulkan.instance_extensions, + config->vulkan.device_extension_count, + config->vulkan.device_extensions, static_cast(config->vulkan.physical_device), static_cast(config->vulkan.device), config->vulkan.queue_family_index, diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 28a9cff414669..cf38efaec29a4 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -602,6 +602,20 @@ typedef struct { uint32_t queue_family_index; /// VkQueue handle. FlutterVulkanQueueHandle queue; + /// The number of instance extensions available for enumerating in the next + /// field. + size_t instance_extension_count; + /// Array of enabled instance extension names. + /// This field is optional; `nullptr` may be specified. + /// For example: + const char** instance_extensions; + /// The number of device extensions available for enumerating in the next + /// field. + size_t device_extension_count; + /// Array of enabled device extension names. + /// This field is optional; `nullptr` may be specified. + /// For example: VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME + const char** device_extensions; FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback; /// The callback invoked when the engine requests a VkImage from the embedder /// for rendering the next frame. diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index 661eaea23b566..3de176b1d8c8b 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -16,6 +16,10 @@ namespace flutter { EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( uint32_t version, VkInstance instance, + size_t instance_extension_count, + const char** instance_extensions, + size_t device_extension_count, + const char** device_extensions, VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family_index, @@ -45,14 +49,17 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( return; } - main_context_ = CreateGrContext(instance, version, ContextType::kRender); + main_context_ = CreateGrContext(instance, version, instance_extension_count, + instance_extensions, device_extension_count, + device_extensions, ContextType::kRender); // TODO(bdero): Add a second (optional) queue+family index to the Embedder API // to allow embedders to specify a dedicated transfer queue for // use by the resource context. Queue families with graphics // capability can always be used for memory transferring, but it // would be adventageous to use a dedicated transter queue here. - resource_context_ = - CreateGrContext(instance, version, ContextType::kResource); + resource_context_ = CreateGrContext( + instance, version, instance_extension_count, instance_extensions, + device_extension_count, device_extensions, ContextType::kResource); valid_ = main_context_ && resource_context_; } @@ -94,6 +101,10 @@ sk_sp EmbedderSurfaceVulkan::CreateResourceContext() const { sk_sp EmbedderSurfaceVulkan::CreateGrContext( VkInstance instance, uint32_t version, + size_t instance_extension_count, + const char** instance_extensions, + size_t device_extension_count, + const char** device_extensions, ContextType context_type) const { uint32_t skia_features = 0; if (!device_.GetPhysicalDeviceFeaturesSkia(&skia_features)) { @@ -123,16 +134,10 @@ sk_sp EmbedderSurfaceVulkan::CreateGrContext( backend_context.fGetProc = get_proc; backend_context.fOwnsInstanceAndDevice = false; - // Activate MEMORY_REQUIREMENTS_2 (available in Vulkan >= 1.1) because VMA - // knows how to take advantage of these features. - if (version >= VK_MAKE_VERSION(1, 1, 0)) { - const char* device_extensions[] = { - VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, - }; - extensions.init(backend_context.fGetProc, backend_context.fInstance, - backend_context.fPhysicalDevice, 0, nullptr, 1, - device_extensions); - } + extensions.init(backend_context.fGetProc, backend_context.fInstance, + backend_context.fPhysicalDevice, instance_extension_count, + instance_extensions, device_extension_count, + device_extensions); GrContextOptions options = MakeDefaultContextOptions(context_type, GrBackendApi::kVulkan); diff --git a/shell/platform/embedder/embedder_surface_vulkan.h b/shell/platform/embedder/embedder_surface_vulkan.h index 2248e783ddc5d..3fa28fa09a7bd 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.h +++ b/shell/platform/embedder/embedder_surface_vulkan.h @@ -31,6 +31,10 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface, EmbedderSurfaceVulkan( uint32_t version, VkInstance instance, + size_t instance_extension_count, + const char** instance_extensions, + size_t device_extension_count, + const char** device_extensions, VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family_index, @@ -69,6 +73,10 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface, sk_sp CreateGrContext(VkInstance instance, uint32_t version, + size_t instance_extension_count, + const char** instance_extensions, + size_t device_extension_count, + const char** device_extensions, ContextType context_type) const; void* GetInstanceProcAddress(VkInstance instance, const char* proc_name); From 5f861aa61bd1cd19f67c5ae30b89295b87588b00 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 10 Jan 2022 13:40:47 -0800 Subject: [PATCH 41/60] Make vulkan names and docstrings clearer for extensions --- shell/platform/embedder/embedder.cc | 8 ++++---- shell/platform/embedder/embedder.h | 22 +++++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 21cfb992b0e76..4605e6db5ed7a 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -466,10 +466,10 @@ InferVulkanPlatformViewCreationCallback( std::make_unique( config->vulkan.version, static_cast(config->vulkan.instance), - config->vulkan.instance_extension_count, - config->vulkan.instance_extensions, - config->vulkan.device_extension_count, - config->vulkan.device_extensions, + config->vulkan.enabled_instance_extension_count, + config->vulkan.enabled_instance_extensions, + config->vulkan.enabled_device_extension_count, + config->vulkan.enabled_device_extensions, static_cast(config->vulkan.physical_device), static_cast(config->vulkan.device), config->vulkan.queue_family_index, diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index cf38efaec29a4..ee9c6b65572a4 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -604,18 +604,26 @@ typedef struct { FlutterVulkanQueueHandle queue; /// The number of instance extensions available for enumerating in the next /// field. - size_t instance_extension_count; - /// Array of enabled instance extension names. + size_t enabled_instance_extension_count; + /// Array of enabled instance extension names. This should match the names + /// passed to `VkInstanceCreateInfo.ppEnabledExtensionNames` when the instance + /// was created, but any subset of enabled instance extensions may be + /// specified. /// This field is optional; `nullptr` may be specified. - /// For example: - const char** instance_extensions; + /// This memory is only accessed during the call to FlutterEngineInitialize. + const char** enabled_instance_extensions; /// The number of device extensions available for enumerating in the next /// field. - size_t device_extension_count; - /// Array of enabled device extension names. + size_t enabled_device_extension_count; + /// Array of enabled logical device extension names. This should match the + /// names passed to `VkDeviceCreateInfo.ppEnabledExtensionNames` when the + /// logical device was created, but any subset of enabled logical device + /// extensions may be specified. /// This field is optional; `nullptr` may be specified. + /// This memory is only accessed during the call to FlutterEngineInitialize. /// For example: VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME - const char** device_extensions; + const char** enabled_device_extensions; + /// The callback invoked when resolving Vulkan function pointers. FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback; /// The callback invoked when the engine requests a VkImage from the embedder /// for rendering the next frame. From fffac576a51adec00efa889b259e08ae7ec30d05 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 10 Jan 2022 13:51:27 -0800 Subject: [PATCH 42/60] Inline vulkan image fields in FlutterVulkanBackingStore --- shell/platform/embedder/embedder.cc | 12 ++++++------ shell/platform/embedder/embedder.h | 6 ++++-- .../tests/embedder_test_backingstore_producer.cc | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 4605e6db5ed7a..7b5bda6ce1107 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -741,15 +741,15 @@ static sk_sp MakeSkSurfaceFromBackingStore( const FlutterBackingStoreConfig& config, const FlutterVulkanBackingStore* vulkan) { #ifdef SHELL_ENABLE_VULKAN - if (!vulkan->image.image) { + if (!vulkan->image) { FML_LOG(ERROR) << "Embedder supplied null Vulkan image."; return nullptr; } GrVkImageInfo image_info = { - .fImage = reinterpret_cast(vulkan->image.image), + .fImage = reinterpret_cast(vulkan->image), .fImageTiling = VK_IMAGE_TILING_OPTIMAL, .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .fFormat = static_cast(vulkan->image.format), + .fFormat = static_cast(vulkan->format), .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | @@ -770,9 +770,9 @@ static sk_sp MakeSkSurfaceFromBackingStore( kTopLeft_GrSurfaceOrigin, // surface origin 1, // sample count flutter::GPUSurfaceVulkan::ColorTypeFromFormat( - static_cast(vulkan->image.format)), // color type - SkColorSpace::MakeSRGB(), // color space - &surface_properties, // surface properties + static_cast(vulkan->format)), // color type + SkColorSpace::MakeSRGB(), // color space + &surface_properties, // surface properties static_cast( vulkan->destruction_callback), // release proc vulkan->user_data // release context diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index ee9c6b65572a4..a2898e5cd38dd 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -1090,13 +1090,15 @@ typedef struct { typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanBackingStore). size_t struct_size; - /// The Vulkan image that the layer will be rendered to. This image must + /// The VkImage handle that the layer will be rendered to. This image must /// already be available for the engine to bind for writing when it's given to /// the engine via the backing store creation callback. The engine will /// perform a host sync for all layers prior to calling the compositor present /// callback, and so the written layer images can be freely bound by the /// embedder without any additional synchronization. - FlutterVulkanImage image; + FlutterVulkanImageHandle image; + /// The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM). + uint32_t format; /// A baton that is not interpreted by the engine in any way. It will be given /// back to the embedder in the destruction callback below. Embedder resources /// may be associated with this baton. diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc index e74258cdf6105..835c5a88f6382 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc @@ -285,9 +285,9 @@ bool EmbedderTestBackingStoreProducer::CreateVulkanImage( backing_store_out->type = kFlutterBackingStoreTypeVulkan; backing_store_out->user_data = surface.get(); backing_store_out->vulkan.user_data = surface.get(); - backing_store_out->vulkan.image.image = + backing_store_out->vulkan.image = reinterpret_cast(image_info.fImage); - backing_store_out->vulkan.image.format = VK_FORMAT_R8G8B8A8_UNORM; + backing_store_out->vulkan.format = VK_FORMAT_R8G8B8A8_UNORM; backing_store_out->vulkan.destruction_callback = [](void* user_data) { reinterpret_cast(user_data)->unref(); }; From f207dfb26dc5ac2503b9d45dfe805506eb38f553 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Thu, 20 Jan 2022 13:15:23 -0800 Subject: [PATCH 43/60] Reference issue # instead of user handle --- shell/platform/embedder/embedder_surface_vulkan.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index 3de176b1d8c8b..20d9766277ea5 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -52,11 +52,11 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( main_context_ = CreateGrContext(instance, version, instance_extension_count, instance_extensions, device_extension_count, device_extensions, ContextType::kRender); - // TODO(bdero): Add a second (optional) queue+family index to the Embedder API - // to allow embedders to specify a dedicated transfer queue for - // use by the resource context. Queue families with graphics - // capability can always be used for memory transferring, but it - // would be adventageous to use a dedicated transter queue here. + // TODO(96954): Add a second (optional) queue+family index to the Embedder API + // to allow embedders to specify a dedicated transfer queue for + // use by the resource context. Queue families with graphics + // capability can always be used for memory transferring, but it + // would be advantageous to use a dedicated transter queue here. resource_context_ = CreateGrContext( instance, version, instance_extension_count, instance_extensions, device_extension_count, device_extensions, ContextType::kResource); From e4dd1c7d1c67a7e303d53497fbd8647384c1913b Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 21 Jan 2022 14:00:34 -0800 Subject: [PATCH 44/60] Explicitly release skia context on test vulkan context destruction to ensure it can never outlive the vulkan device & instance --- testing/test_vulkan_context.cc | 4 ++++ testing/test_vulkan_context.h | 1 + 2 files changed, 5 insertions(+) diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index ec6be6b1a5c06..d00b579a8e5da 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -95,6 +95,10 @@ TestVulkanContext::TestVulkanContext() { context_ = GrDirectContext::MakeVulkan(backend_context, options); } +TestVulkanContext::~TestVulkanContext() { + context_->releaseResourcesAndAbandonContext(); +} + std::optional TestVulkanContext::CreateImage( const SkISize& size) const { TestVulkanImage result; diff --git a/testing/test_vulkan_context.h b/testing/test_vulkan_context.h index 04298003a2741..25d212bf05eb1 100644 --- a/testing/test_vulkan_context.h +++ b/testing/test_vulkan_context.h @@ -21,6 +21,7 @@ namespace testing { class TestVulkanContext : public fml::RefCountedThreadSafe { public: TestVulkanContext(); + ~TestVulkanContext(); std::optional CreateImage(const SkISize& size) const; From 6a76c8219e9ddff17212ed9f504b41f565a8b736 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 21 Jan 2022 14:55:51 -0800 Subject: [PATCH 45/60] Use better names and add docstrings for the test utilities --- .../embedder/tests/embedder_unittests_gl.cc | 24 +++++++------- .../embedder/tests/embedder_unittests_util.cc | 6 ++-- .../embedder/tests/embedder_unittests_util.h | 31 ++++++++++++++++--- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 9ccbe816b0883..94f2eddb42fde 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -1257,8 +1257,8 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositor) { ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); - ASSERT_TRUE(ImageMatchesFixture(ImagePrefix(backend, "gradient.png"), - rendered_scene)); + ASSERT_TRUE(ImageMatchesFixture( + FixtureNameForBackend(backend, "gradient.png"), rendered_scene)); } TEST_F(EmbedderTest, CanRenderGradientWithoutCompositorWithXform) { @@ -1303,7 +1303,7 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithCompositor) { builder.SetDartEntrypoint("render_gradient"); builder.SetRendererConfig(backend, SkISize::Make(800, 600)); builder.SetCompositor(); - builder.SetRenderTargetType(GetTargetFromBackend(backend, true)); + builder.SetRenderTargetType(GetRenderTargetFromBackend(backend, true)); auto rendered_scene = context.GetNextSceneImage(); @@ -1319,8 +1319,8 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithCompositor) { ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); - ASSERT_TRUE(ImageMatchesFixture(ImagePrefix(backend, "gradient.png"), - rendered_scene)); + ASSERT_TRUE(ImageMatchesFixture( + FixtureNameForBackend(backend, "gradient.png"), rendered_scene)); } TEST_F(EmbedderTest, CanRenderGradientWithCompositorWithXform) { @@ -1370,7 +1370,7 @@ TEST_P(EmbedderTestMultiBackend, builder.SetDartEntrypoint("render_gradient_on_non_root_backing_store"); builder.SetRendererConfig(backend, SkISize::Make(800, 600)); builder.SetCompositor(); - builder.SetRenderTargetType(GetTargetFromBackend(backend, true)); + builder.SetRenderTargetType(GetRenderTargetFromBackend(backend, true)); context.GetCompositor().SetNextPresentCallback( [&](const FlutterLayer** layers, size_t layers_count) { @@ -1461,8 +1461,8 @@ TEST_P(EmbedderTestMultiBackend, ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); - ASSERT_TRUE(ImageMatchesFixture(ImagePrefix(backend, "gradient.png"), - rendered_scene)); + ASSERT_TRUE(ImageMatchesFixture( + FixtureNameForBackend(backend, "gradient.png"), rendered_scene)); } TEST_F(EmbedderTest, CanRenderGradientWithCompositorOnNonRootLayerWithXform) { @@ -1822,7 +1822,7 @@ TEST_P(EmbedderTestMultiBackend, builder.SetCompositor(); builder.SetDartEntrypoint("can_display_platform_view_with_pixel_ratio"); - builder.SetRenderTargetType(GetTargetFromBackend(backend, false)); + builder.SetRenderTargetType(GetRenderTargetFromBackend(backend, false)); fml::CountDownLatch latch(1); @@ -1897,8 +1897,8 @@ TEST_P(EmbedderTestMultiBackend, latch.Wait(); - ASSERT_TRUE(ImageMatchesFixture(ImagePrefix(backend, "dpr_noxform.png"), - rendered_scene)); + ASSERT_TRUE(ImageMatchesFixture( + FixtureNameForBackend(backend, "dpr_noxform.png"), rendered_scene)); } TEST_F( @@ -2091,7 +2091,7 @@ TEST_P(EmbedderTestMultiBackend, PlatformViewMutatorsAreValid) { builder.SetCompositor(); builder.SetDartEntrypoint("platform_view_mutators"); - builder.SetRenderTargetType(GetTargetFromBackend(backend, false)); + builder.SetRenderTargetType(GetRenderTargetFromBackend(backend, false)); fml::CountDownLatch latch(1); context.GetCompositor().SetNextPresentCallback( diff --git a/shell/platform/embedder/tests/embedder_unittests_util.cc b/shell/platform/embedder/tests/embedder_unittests_util.cc index d0a114a792992..d076dc1c017c4 100644 --- a/shell/platform/embedder/tests/embedder_unittests_util.cc +++ b/shell/platform/embedder/tests/embedder_unittests_util.cc @@ -70,8 +70,8 @@ bool RasterImagesAreSame(sk_sp a, sk_sp b) { return normalized_a->equals(normalized_b.get()); } -std::string ImagePrefix(EmbedderTestContextType backend, - const std::string& name) { +std::string FixtureNameForBackend(EmbedderTestContextType backend, + const std::string& name) { switch (backend) { case EmbedderTestContextType::kVulkanContext: return "vk_" + name; @@ -80,7 +80,7 @@ std::string ImagePrefix(EmbedderTestContextType backend, } } -EmbedderTestBackingStoreProducer::RenderTargetType GetTargetFromBackend( +EmbedderTestBackingStoreProducer::RenderTargetType GetRenderTargetFromBackend( EmbedderTestContextType backend, bool opengl_framebuffer) { switch (backend) { diff --git a/shell/platform/embedder/tests/embedder_unittests_util.h b/shell/platform/embedder/tests/embedder_unittests_util.h index 227e3bca97d85..f02c1d61c0cc5 100644 --- a/shell/platform/embedder/tests/embedder_unittests_util.h +++ b/shell/platform/embedder/tests/embedder_unittests_util.h @@ -25,13 +25,36 @@ sk_sp CreateRenderSurface(const FlutterLayer& layer, bool RasterImagesAreSame(sk_sp a, sk_sp b); -std::string ImagePrefix(EmbedderTestContextType backend, - const std::string& name); - -EmbedderTestBackingStoreProducer::RenderTargetType GetTargetFromBackend( +/// @brief Prepends a prefix to the name which is unique to the test +/// context type. This is useful for tests that use +/// EmbedderTestMultiBackend and require different fixtures per +/// backend. For OpenGL, the name remains unchanged. +/// @param[in] backend The test context type used to determine the prepended +/// prefix (e.g. `vk_[name]` for Vulkan). +/// @param[in] name The name of the fixture without any special prefixes. +std::string FixtureNameForBackend(EmbedderTestContextType backend, + const std::string& name); + +/// @brief Resolves a render target type for a given backend description. +/// This is useful for tests that use EmbedderTestMultiBackend. +/// @param[in] backend The test context type to resolve the render +/// target for. +/// @param[in] opengl_framebuffer Ignored for all non-OpenGL backends. Flutter +/// supports rendering to both OpenGL textures +/// and framebuffers. When false, the OpenGL +/// texture render target type is returned. +EmbedderTestBackingStoreProducer::RenderTargetType GetRenderTargetFromBackend( EmbedderTestContextType backend, bool opengl_framebuffer); +/// @brief Configures per-backend properties for a given backing store. +/// @param[in] backing_store The backing store to configure. +/// @param[in] backend The test context type used to decide which +/// backend the backing store will be used with. +/// @param[in] opengl_framebuffer Ignored for all non-OpenGL backends. Flutter +/// supports rendering to both OpenGL textures +/// and framebuffers. When false, the backing +/// store is configured to be an OpenGL texture. void ConfigureBackingStore(FlutterBackingStore& backing_store, EmbedderTestContextType backend, bool opengl_framebuffer); From 93d67ab1d289a8215e559a05259a4858f278d768 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 21 Jan 2022 17:41:07 -0800 Subject: [PATCH 46/60] Lifetime comments and remove unnecessary ref count bump --- shell/platform/embedder/embedder.cc | 3 ++- shell/platform/embedder/embedder.h | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 7b5bda6ce1107..666e8b44051b5 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -478,7 +478,8 @@ InferVulkanPlatformViewCreationCallback( return fml::MakeCopyable( [embedder_surface = std::move(embedder_surface), platform_dispatch_table, - external_view_embedder = view_embedder](flutter::Shell& shell) mutable { + external_view_embedder = + std::move(view_embedder)](flutter::Shell& shell) mutable { return std::make_unique( shell, // delegate shell.GetTaskRunners(), // task runners diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index a2898e5cd38dd..9a112c322fece 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -592,11 +592,13 @@ typedef struct { /// The Vulkan API version. This should match the value set in /// VkApplicationInfo::apiVersion when the VkInstance was created. uint32_t version; - /// VkInstance handle. + /// VkInstance handle. Must not be destroyed before `FlutterEngineShutdown` is + /// called. FlutterVulkanInstanceHandle instance; /// VkPhysicalDevice handle. FlutterVulkanPhysicalDeviceHandle physical_device; - /// VkDevice handle. + /// VkDevice handle. Must not be destroyed before `FlutterEngineShutdown` is + /// called. FlutterVulkanDeviceHandle device; /// The queue family index of the VkQueue supplied in the next field. uint32_t queue_family_index; From 0d1687c6dce537f386aa75d3df2f8cd7e94f6389 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sat, 22 Jan 2022 12:48:58 -0800 Subject: [PATCH 47/60] Use a pointer to a const FlutterVulkanImage instead of inlining fields in backing store --- shell/platform/embedder/embedder.cc | 10 +++--- shell/platform/embedder/embedder.h | 16 ++++----- .../embedder_test_backingstore_producer.cc | 34 +++++++++++++------ .../embedder_test_backingstore_producer.h | 5 +++ .../tests/embedder_test_compositor_vulkan.cc | 6 ++-- 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 666e8b44051b5..0f826a570104f 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -747,10 +747,10 @@ static sk_sp MakeSkSurfaceFromBackingStore( return nullptr; } GrVkImageInfo image_info = { - .fImage = reinterpret_cast(vulkan->image), + .fImage = reinterpret_cast(vulkan->image->image), .fImageTiling = VK_IMAGE_TILING_OPTIMAL, .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .fFormat = static_cast(vulkan->format), + .fFormat = static_cast(vulkan->image->format), .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | @@ -771,9 +771,9 @@ static sk_sp MakeSkSurfaceFromBackingStore( kTopLeft_GrSurfaceOrigin, // surface origin 1, // sample count flutter::GPUSurfaceVulkan::ColorTypeFromFormat( - static_cast(vulkan->format)), // color type - SkColorSpace::MakeSRGB(), // color space - &surface_properties, // surface properties + static_cast(vulkan->image->format)), // color type + SkColorSpace::MakeSRGB(), // color space + &surface_properties, // surface properties static_cast( vulkan->destruction_callback), // release proc vulkan->user_data // release context diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 9a112c322fece..a8a2592c624bc 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -1092,15 +1092,13 @@ typedef struct { typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanBackingStore). size_t struct_size; - /// The VkImage handle that the layer will be rendered to. This image must - /// already be available for the engine to bind for writing when it's given to - /// the engine via the backing store creation callback. The engine will - /// perform a host sync for all layers prior to calling the compositor present - /// callback, and so the written layer images can be freely bound by the - /// embedder without any additional synchronization. - FlutterVulkanImageHandle image; - /// The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM). - uint32_t format; + /// The image that the layer will be rendered to. This image must already be + /// available for the engine to bind for writing when it's given to the engine + /// via the backing store creation callback. The engine will perform a host + /// sync for all layers prior to calling the compositor present callback, and + /// so the written layer images can be freely bound by the embedder without + /// any additional synchronization. + const FlutterVulkanImage* image; /// A baton that is not interpreted by the engine in any way. It will be given /// back to the embedder in the destruction callback below. Embedder resources /// may be associated with this baton. diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc index 835c5a88f6382..3ea5c7a90bcbb 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc @@ -283,16 +283,30 @@ bool EmbedderTestBackingStoreProducer::CreateVulkanImage( return false; } backing_store_out->type = kFlutterBackingStoreTypeVulkan; - backing_store_out->user_data = surface.get(); - backing_store_out->vulkan.user_data = surface.get(); - backing_store_out->vulkan.image = - reinterpret_cast(image_info.fImage); - backing_store_out->vulkan.format = VK_FORMAT_R8G8B8A8_UNORM; - backing_store_out->vulkan.destruction_callback = [](void* user_data) { - reinterpret_cast(user_data)->unref(); - }; - // The balancing unref is in the destruction callback. - surface->ref(); + + FlutterVulkanImage* image = new FlutterVulkanImage(); + image->image = reinterpret_cast(image_info.fImage); + image->format = VK_FORMAT_R8G8B8A8_UNORM; + backing_store_out->vulkan.image = image; + + // Collect all allocated resources in the destruction_callback. + { + UserData* user_data = new UserData(); + user_data->image = image; + user_data->surface = surface.get(); + + backing_store_out->user_data = user_data; + backing_store_out->vulkan.user_data = user_data; + backing_store_out->vulkan.destruction_callback = [](void* user_data) { + UserData* d = reinterpret_cast(user_data); + d->surface->unref(); + delete d->image; + delete d; + }; + + // The balancing unref is in the destruction callback. + surface->ref(); + } return true; #else diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h index b35c04d55bb68..956c565d29f43 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.h +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.h @@ -24,6 +24,11 @@ namespace testing { class EmbedderTestBackingStoreProducer { public: + struct UserData { + SkSurface* surface; + FlutterVulkanImage* image; + }; + enum class RenderTargetType { kSoftwareBuffer, kOpenGLFramebuffer, diff --git a/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc b/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc index f5fc6884e4766..a932260513b98 100644 --- a/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc +++ b/shell/platform/embedder/tests/embedder_test_compositor_vulkan.cc @@ -6,6 +6,7 @@ #include "flutter/fml/logging.h" #include "flutter/shell/platform/embedder/tests/embedder_assertions.h" +#include "flutter/shell/platform/embedder/tests/embedder_test_backingstore_producer.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter { @@ -57,8 +58,9 @@ bool EmbedderTestCompositorVulkan::UpdateOffscrenComposition( switch (layer->type) { case kFlutterLayerContentTypeBackingStore: layer_image = - reinterpret_cast(layer->backing_store->user_data) - ->makeImageSnapshot(); + reinterpret_cast( + layer->backing_store->user_data) + ->surface->makeImageSnapshot(); break; case kFlutterLayerContentTypePlatformView: layer_image = From a510bfdfecf17c224ef2303cbf6d25330d774913 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sat, 22 Jan 2022 14:28:14 -0800 Subject: [PATCH 48/60] Force refcounted skia contexts to collect in EmbedderSurfaceVulkan --- shell/platform/embedder/embedder_surface_vulkan.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index 20d9766277ea5..8b818116551a5 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -64,7 +64,10 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( valid_ = main_context_ && resource_context_; } -EmbedderSurfaceVulkan::~EmbedderSurfaceVulkan() = default; +EmbedderSurfaceVulkan::~EmbedderSurfaceVulkan() { + main_context_->releaseResourcesAndAbandonContext(); + resource_context_->releaseResourcesAndAbandonContext(); +} // |GPUSurfaceVulkanDelegate| const vulkan::VulkanProcTable& EmbedderSurfaceVulkan::vk() { From a48c201477abdb0d2b440e8188390d52ac8c23f7 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 31 Jan 2022 15:08:18 -0800 Subject: [PATCH 49/60] Fix OS defines --- testing/test_vulkan_context.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index d00b579a8e5da..232d557f335aa 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -15,9 +15,9 @@ #include "third_party/skia/include/gpu/vk/GrVkExtensions.h" #include "vulkan/vulkan_core.h" -#ifdef OS_MACOSX +#ifdef FML_OS_MACOSX #define VULKAN_SO_PATH "libvk_swiftshader.dylib" -#elif OS_WIN +#elif FML_OS_WIN #define VULKAN_SO_PATH "vk_swiftshader.dll" #else #define VULKAN_SO_PATH "libvk_swiftshader.so" From aec5449b71c0f35807b2d3f8220aab4d5d1351d0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 11:33:56 -0800 Subject: [PATCH 50/60] Disable swiftshader tests for FEMU --- shell/platform/embedder/BUILD.gn | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 1e6ac775d5e82..9b6136bd06aea 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -11,8 +11,10 @@ import("//flutter/testing/testing.gni") declare_args() { embedder_enable_software = shell_enable_software - embedder_enable_vulkan = shell_enable_vulkan - embedder_enable_gl = shell_enable_gl + + # The swiftshader unittests don't work on Fuchsia yet. + embedder_enable_vulkan = !is_fuchsia && shell_enable_vulkan + embedder_enable_gl = !is_fuchsia && shell_enable_gl embedder_enable_metal = shell_enable_metal } From 63b879f73d82e5ac7c5945942c7f2349dd65dd8d Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 11:53:47 -0800 Subject: [PATCH 51/60] Revert "Disable swiftshader tests for FEMU" This reverts commit b4f46cd3de8aeba22a6f002c58285c5c4090e885. --- shell/platform/embedder/BUILD.gn | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 9b6136bd06aea..1e6ac775d5e82 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -11,10 +11,8 @@ import("//flutter/testing/testing.gni") declare_args() { embedder_enable_software = shell_enable_software - - # The swiftshader unittests don't work on Fuchsia yet. - embedder_enable_vulkan = !is_fuchsia && shell_enable_vulkan - embedder_enable_gl = !is_fuchsia && shell_enable_gl + embedder_enable_vulkan = shell_enable_vulkan + embedder_enable_gl = shell_enable_gl embedder_enable_metal = shell_enable_metal } From 2442a950c8411641542626c2c55a96930866f47a Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 12:17:56 -0800 Subject: [PATCH 52/60] Try falling back to libvulkan.so if swiftshader is missing --- testing/test_vulkan_context.cc | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index 232d557f335aa..718982caf60b2 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -9,7 +9,8 @@ #include "flutter/shell/common/context_options.h" #include "flutter/testing/test_vulkan_context.h" -#include "fml/memory/ref_ptr.h" +#include "flutter/fml/file.h" +#include "flutter/fml/memory/ref_ptr.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/vk/GrVkExtensions.h" @@ -31,9 +32,18 @@ TestVulkanContext::TestVulkanContext() { // Initialize basic Vulkan state using the Swiftshader ICD. // --------------------------------------------------------------------------- - vk_ = fml::MakeRefCounted(VULKAN_SO_PATH); + const char* vulkan_icd = VULKAN_SO_PATH; + + auto fd = fml::OpenDirectory(".", false, fml::FilePermission::kRead); + if (!fml::FileExists(fd, vulkan_icd)) { + FML_LOG(WARNING) << "Couldn't find Vulkan ICD \"" << vulkan_icd + << "\", trying \"libvulkan.so\" instead."; + vulkan_icd = "libvulkan.so"; + } + + vk_ = fml::MakeRefCounted(vulkan_icd); if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { - FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; + FML_LOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; return; } @@ -42,17 +52,17 @@ TestVulkanContext::TestVulkanContext() { *vk_, "Flutter Unittests", {}, VK_MAKE_VERSION(1, 0, 0), VK_MAKE_VERSION(1, 0, 0), true)); if (!application_->IsValid()) { - FML_DLOG(ERROR) << "Failed to initialize basic Vulkan state."; + FML_LOG(ERROR) << "Failed to initialize basic Vulkan state."; return; } if (!vk_->AreInstanceProcsSetup()) { - FML_DLOG(ERROR) << "Failed to acquire full proc table."; + FML_LOG(ERROR) << "Failed to acquire full proc table."; return; } device_ = application_->AcquireFirstCompatibleLogicalDevice(); if (!device_ || !device_->IsValid()) { - FML_DLOG(ERROR) << "Failed to create compatible logical device."; + FML_LOG(ERROR) << "Failed to create compatible logical device."; return; } From f5bfc9a89740dd2086d8464c89065aaaff76770c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 12:38:53 -0800 Subject: [PATCH 53/60] Use NativeLibrary to detect existence of the ICD --- testing/test_vulkan_context.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index 718982caf60b2..51c745f013e18 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -9,8 +9,8 @@ #include "flutter/shell/common/context_options.h" #include "flutter/testing/test_vulkan_context.h" -#include "flutter/fml/file.h" #include "flutter/fml/memory/ref_ptr.h" +#include "flutter/fml/native_library.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/vk/GrVkExtensions.h" @@ -34,8 +34,9 @@ TestVulkanContext::TestVulkanContext() { const char* vulkan_icd = VULKAN_SO_PATH; - auto fd = fml::OpenDirectory(".", false, fml::FilePermission::kRead); - if (!fml::FileExists(fd, vulkan_icd)) { + // TODO(96949): Clean this up and pass a native library directly to + // VulkanProcTable. + if (!fml::NativeLibrary::Create(VULKAN_SO_PATH)) { FML_LOG(WARNING) << "Couldn't find Vulkan ICD \"" << vulkan_icd << "\", trying \"libvulkan.so\" instead."; vulkan_icd = "libvulkan.so"; From 9f2584d7c2bcf6de7cd7bba59673f0e5fb54f3c8 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 13:01:04 -0800 Subject: [PATCH 54/60] Add test debug logs to see what's going on in FEMU --- testing/test_vulkan_context.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index 51c745f013e18..f68ea4435c661 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -28,6 +28,8 @@ namespace flutter { namespace testing { TestVulkanContext::TestVulkanContext() { + FML_LOG(ERROR) << "====bdero==== Attempting to construct TestVulkanContext."; + // --------------------------------------------------------------------------- // Initialize basic Vulkan state using the Swiftshader ICD. // --------------------------------------------------------------------------- @@ -104,6 +106,13 @@ TestVulkanContext::TestVulkanContext() { MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kVulkan); options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; context_ = GrDirectContext::MakeVulkan(backend_context, options); + + FML_LOG(ERROR) << "====bdero==== This message means that the " + "TestVulkanContext was successfully " + "constructed. This means that mandatory procs were " + "successfully resolved from " + "the Vulkan ICD. The ICD successfully loaded was \"" + << vulkan_icd << "\"!"; } TestVulkanContext::~TestVulkanContext() { From 166b26a5581740b90dba4bbf8e01f1eae11dd112 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 13:02:46 -0800 Subject: [PATCH 55/60] Add log so that the ICD being used is always printed --- testing/test_vulkan_context.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index f68ea4435c661..684ebe01e4aea 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -44,6 +44,8 @@ TestVulkanContext::TestVulkanContext() { vulkan_icd = "libvulkan.so"; } + FML_LOG(WARNING) << "Using Vulkan ICD: " << vulkan_icd; + vk_ = fml::MakeRefCounted(vulkan_icd); if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { FML_LOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; From 20a2368f8266036c35f59ce211eee467f6120c18 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 14:08:05 -0800 Subject: [PATCH 56/60] Remove temp logs --- testing/test_vulkan_context.cc | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index 684ebe01e4aea..ebc6a964baba5 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -28,8 +28,6 @@ namespace flutter { namespace testing { TestVulkanContext::TestVulkanContext() { - FML_LOG(ERROR) << "====bdero==== Attempting to construct TestVulkanContext."; - // --------------------------------------------------------------------------- // Initialize basic Vulkan state using the Swiftshader ICD. // --------------------------------------------------------------------------- @@ -39,12 +37,12 @@ TestVulkanContext::TestVulkanContext() { // TODO(96949): Clean this up and pass a native library directly to // VulkanProcTable. if (!fml::NativeLibrary::Create(VULKAN_SO_PATH)) { - FML_LOG(WARNING) << "Couldn't find Vulkan ICD \"" << vulkan_icd - << "\", trying \"libvulkan.so\" instead."; + FML_LOG(ERROR) << "Couldn't find Vulkan ICD \"" << vulkan_icd + << "\", trying \"libvulkan.so\" instead."; vulkan_icd = "libvulkan.so"; } - FML_LOG(WARNING) << "Using Vulkan ICD: " << vulkan_icd; + FML_LOG(INFO) << "Using Vulkan ICD: " << vulkan_icd; vk_ = fml::MakeRefCounted(vulkan_icd); if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { @@ -108,13 +106,6 @@ TestVulkanContext::TestVulkanContext() { MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kVulkan); options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; context_ = GrDirectContext::MakeVulkan(backend_context, options); - - FML_LOG(ERROR) << "====bdero==== This message means that the " - "TestVulkanContext was successfully " - "constructed. This means that mandatory procs were " - "successfully resolved from " - "the Vulkan ICD. The ICD successfully loaded was \"" - << vulkan_icd << "\"!"; } TestVulkanContext::~TestVulkanContext() { From 8bbacf0b08f44776bdc515aa34c55c2f22c583e6 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 18:54:17 -0800 Subject: [PATCH 57/60] Guard against null contexts in destructors --- shell/platform/embedder/embedder_surface_vulkan.cc | 8 ++++++-- testing/test_vulkan_context.cc | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index 8b818116551a5..b3918a2420070 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -65,8 +65,12 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( } EmbedderSurfaceVulkan::~EmbedderSurfaceVulkan() { - main_context_->releaseResourcesAndAbandonContext(); - resource_context_->releaseResourcesAndAbandonContext(); + if (main_context_) { + main_context_->releaseResourcesAndAbandonContext(); + } + if (resource_context_) { + resource_context_->releaseResourcesAndAbandonContext(); + } } // |GPUSurfaceVulkanDelegate| diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index ebc6a964baba5..56eeb558cc975 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -109,7 +109,9 @@ TestVulkanContext::TestVulkanContext() { } TestVulkanContext::~TestVulkanContext() { - context_->releaseResourcesAndAbandonContext(); + if (context_) { + context_->releaseResourcesAndAbandonContext(); + } } std::optional TestVulkanContext::CreateImage( From 82e8c97419ae2f5cd0f4e896b0d6986f00c78426 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 20:08:21 -0800 Subject: [PATCH 58/60] Test logs --- .../embedder/tests/embedder_config_builder.cc | 4 ++++ .../platform/embedder/tests/embedder_test.cc | 4 ++++ .../embedder/tests/embedder_unittests.cc | 19 +++++++++++++++++++ testing/test_vulkan_context.cc | 3 +++ 4 files changed, 30 insertions(+) diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index ae63a3220f41f..2b0f079bd537e 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -201,6 +201,7 @@ void EmbedderConfigBuilder::SetMetalRendererConfig(SkISize surface_size) { void EmbedderConfigBuilder::SetVulkanRendererConfig(SkISize surface_size) { #ifdef SHELL_ENABLE_VULKAN + FML_LOG(ERROR) << "==== bdero ==== SetVulkanRendererConfig"; renderer_config_.type = FlutterRendererType::kVulkan; renderer_config_.vulkan = vulkan_renderer_config_; context_.SetupSurface(surface_size); @@ -468,9 +469,12 @@ void EmbedderConfigBuilder::InitializeMetalRendererConfig() { #ifdef SHELL_ENABLE_VULKAN void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { + FML_LOG(ERROR) << "==== bdero ==== InitializeVulkanRendererConfig"; if (context_.GetContextType() != EmbedderTestContextType::kVulkanContext) { + FML_LOG(ERROR) << "==== bdero ==== InitializeVulkanRendererConfig SKIPPED"; return; } + FML_LOG(ERROR) << "==== bdero ==== context_.GetContextType() must be Vulkan"; vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); vulkan_renderer_config_.version = diff --git a/shell/platform/embedder/tests/embedder_test.cc b/shell/platform/embedder/tests/embedder_test.cc index 9a315dec3c415..176b6d666f1fc 100644 --- a/shell/platform/embedder/tests/embedder_test.cc +++ b/shell/platform/embedder/tests/embedder_test.cc @@ -25,6 +25,7 @@ std::string EmbedderTest::GetFixturesDirectory() const { EmbedderTestContext& EmbedderTest::GetEmbedderContext( EmbedderTestContextType type) { + FML_LOG(ERROR) << "==== bdero ==== GetEmbedderContext"; // Setup the embedder context lazily instead of in the constructor because we // don't to do all the work if the test won't end up using context. if (!embedder_contexts_[type]) { @@ -36,6 +37,9 @@ EmbedderTestContext& EmbedderTest::GetEmbedderContext( break; #ifdef SHELL_ENABLE_VULKAN case EmbedderTestContextType::kVulkanContext: + + FML_LOG(ERROR) << "==== bdero ==== GetEmbedderContext: " + "EmbedderTestContextVulkan was constructed"; embedder_contexts_[type] = std::make_unique(GetFixturesDirectory()); break; diff --git a/shell/platform/embedder/tests/embedder_unittests.cc b/shell/platform/embedder/tests/embedder_unittests.cc index 5dccfab382910..598ad9e647235 100644 --- a/shell/platform/embedder/tests/embedder_unittests.cc +++ b/shell/platform/embedder/tests/embedder_unittests.cc @@ -592,6 +592,7 @@ TEST_F(EmbedderTest, VMAndIsolateSnapshotSizesAreRedundantInAOTMode) { /// TEST_F(EmbedderTest, CompositorMustBeAbleToRenderKnownSceneWithSoftwareCompositor) { + FML_LOG(ERROR) << "====bdero==== 0 BEGIN"; auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext); EmbedderConfigBuilder builder(context); @@ -606,8 +607,12 @@ TEST_F(EmbedderTest, auto scene_image = context.GetNextSceneImage(); + FML_LOG(ERROR) << "====bdero==== 1 GetNextSceneImage"; + context.GetCompositor().SetNextPresentCallback( [&](const FlutterLayer** layers, size_t layers_count) { + FML_LOG(ERROR) << "====bdero==== Present callback BEGIN"; + ASSERT_EQ(layers_count, 5u); // Layer Root @@ -693,12 +698,17 @@ TEST_F(EmbedderTest, ASSERT_EQ(*layers[4], layer); } + FML_LOG(ERROR) << "====bdero==== Present callback latch"; latch.CountDown(); + + FML_LOG(ERROR) << "====bdero==== Present callback END"; }); context.GetCompositor().SetPlatformViewRendererCallback( [&](const FlutterLayer& layer, GrDirectContext* /* don't use because software compositor */) -> sk_sp { + FML_LOG(ERROR) << "====bdero==== Renderer callback BEGIN"; + auto surface = CreateRenderSurface( layer, nullptr /* null because software compositor */); auto canvas = surface->getCanvas(); @@ -731,6 +741,7 @@ TEST_F(EmbedderTest, << "Test was asked to composite an unknown platform view."; } + FML_LOG(ERROR) << "====bdero==== Renderer callback END"; return surface->makeImageSnapshot(); }); @@ -739,8 +750,12 @@ TEST_F(EmbedderTest, CREATE_NATIVE_ENTRY( [&latch](Dart_NativeArguments args) { latch.CountDown(); })); + FML_LOG(ERROR) << "====bdero==== 2 Before LaunchEngine"; + auto engine = builder.LaunchEngine(); + FML_LOG(ERROR) << "====bdero==== 3 After LaunchEngine"; + // Send a window metrics events so frames may be scheduled. FlutterWindowMetricsEvent event = {}; event.struct_size = sizeof(event); @@ -755,12 +770,16 @@ TEST_F(EmbedderTest, kSuccess); ASSERT_TRUE(engine.is_valid()); + FML_LOG(ERROR) << "====bdero==== 4 Before latch"; latch.Wait(); + FML_LOG(ERROR) << "====bdero==== 5 After latch"; ASSERT_TRUE(ImageMatchesFixture("compositor_software.png", scene_image)); // There should no present calls on the root surface. ASSERT_EQ(context.GetSurfacePresentCount(), 0u); + + FML_LOG(ERROR) << "====bdero==== 6 END"; } //------------------------------------------------------------------------------ diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index 56eeb558cc975..d093cb9357360 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -109,9 +109,12 @@ TestVulkanContext::TestVulkanContext() { } TestVulkanContext::~TestVulkanContext() { + FML_LOG(ERROR) << "~TestVulkanContext begin"; if (context_) { context_->releaseResourcesAndAbandonContext(); } + + FML_LOG(ERROR) << "~TestVulkanContext end"; } std::optional TestVulkanContext::CreateImage( From eedf60bd5b66a2672b8f9dfe91326b523704a96d Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 22:08:39 -0800 Subject: [PATCH 59/60] Lazily create the backingstore_producer vulkan context --- .../embedder/tests/embedder_test_backingstore_producer.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc index 3ea5c7a90bcbb..94fa852d10c44 100644 --- a/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc +++ b/shell/platform/embedder/tests/embedder_test_backingstore_producer.cc @@ -25,7 +25,7 @@ EmbedderTestBackingStoreProducer::EmbedderTestBackingStoreProducer( #endif #ifdef SHELL_ENABLE_VULKAN , - test_vulkan_context_(fml::MakeRefCounted()) + test_vulkan_context_(nullptr) #endif { } @@ -241,6 +241,10 @@ bool EmbedderTestBackingStoreProducer::CreateVulkanImage( const FlutterBackingStoreConfig* config, FlutterBackingStore* backing_store_out) { #ifdef SHELL_ENABLE_VULKAN + if (!test_vulkan_context_) { + test_vulkan_context_ = fml::MakeRefCounted(); + } + auto surface_size = SkISize::Make(config->size.width, config->size.height); TestVulkanImage* test_image = new TestVulkanImage( std::move(test_vulkan_context_->CreateImage(surface_size).value())); From 63f0b5fc7d4efcd5ec50035fd8115944df1ff110 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 1 Feb 2022 22:31:56 -0800 Subject: [PATCH 60/60] Revert "Test logs" This reverts commit 01dee39503b6c66556d8f4b725397a88e2ad8e07. --- .../embedder/tests/embedder_config_builder.cc | 4 ---- .../platform/embedder/tests/embedder_test.cc | 4 ---- .../embedder/tests/embedder_unittests.cc | 19 ------------------- testing/test_vulkan_context.cc | 3 --- 4 files changed, 30 deletions(-) diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index 2b0f079bd537e..ae63a3220f41f 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -201,7 +201,6 @@ void EmbedderConfigBuilder::SetMetalRendererConfig(SkISize surface_size) { void EmbedderConfigBuilder::SetVulkanRendererConfig(SkISize surface_size) { #ifdef SHELL_ENABLE_VULKAN - FML_LOG(ERROR) << "==== bdero ==== SetVulkanRendererConfig"; renderer_config_.type = FlutterRendererType::kVulkan; renderer_config_.vulkan = vulkan_renderer_config_; context_.SetupSurface(surface_size); @@ -469,12 +468,9 @@ void EmbedderConfigBuilder::InitializeMetalRendererConfig() { #ifdef SHELL_ENABLE_VULKAN void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { - FML_LOG(ERROR) << "==== bdero ==== InitializeVulkanRendererConfig"; if (context_.GetContextType() != EmbedderTestContextType::kVulkanContext) { - FML_LOG(ERROR) << "==== bdero ==== InitializeVulkanRendererConfig SKIPPED"; return; } - FML_LOG(ERROR) << "==== bdero ==== context_.GetContextType() must be Vulkan"; vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); vulkan_renderer_config_.version = diff --git a/shell/platform/embedder/tests/embedder_test.cc b/shell/platform/embedder/tests/embedder_test.cc index 176b6d666f1fc..9a315dec3c415 100644 --- a/shell/platform/embedder/tests/embedder_test.cc +++ b/shell/platform/embedder/tests/embedder_test.cc @@ -25,7 +25,6 @@ std::string EmbedderTest::GetFixturesDirectory() const { EmbedderTestContext& EmbedderTest::GetEmbedderContext( EmbedderTestContextType type) { - FML_LOG(ERROR) << "==== bdero ==== GetEmbedderContext"; // Setup the embedder context lazily instead of in the constructor because we // don't to do all the work if the test won't end up using context. if (!embedder_contexts_[type]) { @@ -37,9 +36,6 @@ EmbedderTestContext& EmbedderTest::GetEmbedderContext( break; #ifdef SHELL_ENABLE_VULKAN case EmbedderTestContextType::kVulkanContext: - - FML_LOG(ERROR) << "==== bdero ==== GetEmbedderContext: " - "EmbedderTestContextVulkan was constructed"; embedder_contexts_[type] = std::make_unique(GetFixturesDirectory()); break; diff --git a/shell/platform/embedder/tests/embedder_unittests.cc b/shell/platform/embedder/tests/embedder_unittests.cc index 598ad9e647235..5dccfab382910 100644 --- a/shell/platform/embedder/tests/embedder_unittests.cc +++ b/shell/platform/embedder/tests/embedder_unittests.cc @@ -592,7 +592,6 @@ TEST_F(EmbedderTest, VMAndIsolateSnapshotSizesAreRedundantInAOTMode) { /// TEST_F(EmbedderTest, CompositorMustBeAbleToRenderKnownSceneWithSoftwareCompositor) { - FML_LOG(ERROR) << "====bdero==== 0 BEGIN"; auto& context = GetEmbedderContext(EmbedderTestContextType::kSoftwareContext); EmbedderConfigBuilder builder(context); @@ -607,12 +606,8 @@ TEST_F(EmbedderTest, auto scene_image = context.GetNextSceneImage(); - FML_LOG(ERROR) << "====bdero==== 1 GetNextSceneImage"; - context.GetCompositor().SetNextPresentCallback( [&](const FlutterLayer** layers, size_t layers_count) { - FML_LOG(ERROR) << "====bdero==== Present callback BEGIN"; - ASSERT_EQ(layers_count, 5u); // Layer Root @@ -698,17 +693,12 @@ TEST_F(EmbedderTest, ASSERT_EQ(*layers[4], layer); } - FML_LOG(ERROR) << "====bdero==== Present callback latch"; latch.CountDown(); - - FML_LOG(ERROR) << "====bdero==== Present callback END"; }); context.GetCompositor().SetPlatformViewRendererCallback( [&](const FlutterLayer& layer, GrDirectContext* /* don't use because software compositor */) -> sk_sp { - FML_LOG(ERROR) << "====bdero==== Renderer callback BEGIN"; - auto surface = CreateRenderSurface( layer, nullptr /* null because software compositor */); auto canvas = surface->getCanvas(); @@ -741,7 +731,6 @@ TEST_F(EmbedderTest, << "Test was asked to composite an unknown platform view."; } - FML_LOG(ERROR) << "====bdero==== Renderer callback END"; return surface->makeImageSnapshot(); }); @@ -750,12 +739,8 @@ TEST_F(EmbedderTest, CREATE_NATIVE_ENTRY( [&latch](Dart_NativeArguments args) { latch.CountDown(); })); - FML_LOG(ERROR) << "====bdero==== 2 Before LaunchEngine"; - auto engine = builder.LaunchEngine(); - FML_LOG(ERROR) << "====bdero==== 3 After LaunchEngine"; - // Send a window metrics events so frames may be scheduled. FlutterWindowMetricsEvent event = {}; event.struct_size = sizeof(event); @@ -770,16 +755,12 @@ TEST_F(EmbedderTest, kSuccess); ASSERT_TRUE(engine.is_valid()); - FML_LOG(ERROR) << "====bdero==== 4 Before latch"; latch.Wait(); - FML_LOG(ERROR) << "====bdero==== 5 After latch"; ASSERT_TRUE(ImageMatchesFixture("compositor_software.png", scene_image)); // There should no present calls on the root surface. ASSERT_EQ(context.GetSurfacePresentCount(), 0u); - - FML_LOG(ERROR) << "====bdero==== 6 END"; } //------------------------------------------------------------------------------ diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index d093cb9357360..56eeb558cc975 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -109,12 +109,9 @@ TestVulkanContext::TestVulkanContext() { } TestVulkanContext::~TestVulkanContext() { - FML_LOG(ERROR) << "~TestVulkanContext begin"; if (context_) { context_->releaseResourcesAndAbandonContext(); } - - FML_LOG(ERROR) << "~TestVulkanContext end"; } std::optional TestVulkanContext::CreateImage(