diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 1c0542cef88a8..ce588c9793326 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -368,6 +368,42 @@ 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; + } + assert(false); // TODO(bdero) + +//#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, @@ -430,6 +466,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; } diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index a491baf84d09d..1cb1930469678 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -495,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 @@ -542,30 +542,80 @@ typedef struct { FlutterMetalTextureFrameCallback external_texture_frame_callback; } FlutterMetalRendererConfig; -typedef uintptr_t* (*FlutterVulkanGetNextImageCallback)(void* /* user data */); +/// Alias for VkInstance. +typedef const uint64_t* FlutterVulkanInstanceHandle; -typedef void* (*ProcAddressCallback)(void* user /* in */, - const char* pName /* in */); -typedef void* (*InstanceProcAddressCallback)(void* user /* in */, - uintptr_t* instance /* in */, - const char* pName /* in */); -typedef uintptr_t* (*UintPtrCallback)(void* user /* in */); +/// Alias for VkPhysicalDevice. +typedef const uint64_t* FlutterVulkanPhysicalDeviceHandle; + +/// Alias for VkDevice. +typedef const uint64_t* FlutterVulkanDeviceHandle; + +/// Alias for VkImage. +typedef const uint64_t* FlutterVulkanImageHandle; typedef struct { - /// The size of this struct. Must be sizeof(FlutterVulkanRendererConfig). + /// The size of this struct. Must be sizeof(FlutterVulkanImage). size_t struct_size; - + /// Embedder provided unique identifier to the image. Given that the `image` + /// handle is passed to the engine to render to, the image is itself owned by + /// the embedder. This `image_id` is then also given to the embedder in the + /// present callback. + int64_t image_id; + /// 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; - /// Platform Callbacks - ProcAddressCallback get_proc_address_callback; - InstanceProcAddressCallback get_instance_proc_address_callback; - UintPtrCallback get_instance_handle_callback; - UintPtrCallback get_physical_device_handle_callback; - UintPtrCallback get_device_handle_callback; +/// 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 */); - FlutterVulkanGetNextImageCallback acquire_next_image_callback; - VoidCallback terminate_callback; +/// 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. The `image_id` here corresponds to the image_id provided by the +/// embedder in the `FlutterVulkanImageCallback` callback. +typedef bool (*FlutterVulkanPresentCallback)( + void* /* user data */, + const FlutterVulkanImage* /* image */); +typedef uint64_t* (*Uint64Callback)(void* /* user data */); + +typedef uint64_t* (*FlutterVulkanPresentImageCallback)(void* /* user data */, + uint64_t* /* image */); + +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; + ProcResolver get_proc_address_callback; + 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; @@ -1022,11 +1072,13 @@ typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanBackingStore). size_t struct_size; - /// VkImage handle. - uint64_t handle; - - /// VkSemaphore signaled when engine is done writing image. - uint64_t image_ready; + /// 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 { 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..143c77f405825 --- /dev/null +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.cc @@ -0,0 +1,50 @@ +// 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" + +namespace flutter { +namespace testing { + +EmbedderTestContextVulkan::EmbedderTestContextVulkan(std::string assets_path) + : EmbedderTestContext(assets_path) { + //vulkan_context_ = std::make_unique(); +} + +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..1341ef139f2df --- /dev/null +++ b/shell/platform/embedder/tests/embedder_test_context_vulkan.h @@ -0,0 +1,46 @@ +// 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 "flutter/shell/platform/embedder/tests/embedder_test_context.h" +#include "flutter/testing/test_vulkan_context.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; + + TestVulkanContext* GetTestVulkanContext(); + + private: + // This allows the builder to access the hooks. + friend class EmbedderConfigBuilder; + 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/testing/BUILD.gn b/testing/BUILD.gn index 26f04e82f0e03..7d53d2e6f0036 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn @@ -109,11 +109,6 @@ if (enable_unittests) { source_set("vulkan") { testonly = true - sources = [ - "test_vulkan_context.h", - "test_vulkan_context.cc", - ] - deps = [ ":skia", "//flutter/fml", diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc deleted file mode 100644 index 364cac403f505..0000000000000 --- a/testing/test_vulkan_context.cc +++ /dev/null @@ -1,35 +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 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 { - -TestVulkanContext::TestVulkanContext() { - 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()); -} - -TestVulkanContext::~TestVulkanContext() = default; - -} // namespace flutter diff --git a/testing/test_vulkan_context.h b/testing/test_vulkan_context.h deleted file mode 100644 index 0c35b061bde5e..0000000000000 --- a/testing/test_vulkan_context.h +++ /dev/null @@ -1,29 +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(); - - private: - fml::RefPtr vk_; - std::unique_ptr application_; - std::unique_ptr logical_device_; -}; - -} // namespace flutter - -#endif // FLUTTER_TESTING_TEST_VULKAN_CONTEXT_H_